8.3.1 Как MySQL использует индексы
Индексы используются для быстрого поиска строк со специфическими значениями столбцов. Без индекса MySQL должно начинать с первой строки и читать всю таблицу, чтобы найти нужные строки. Чем больше таблица, тем больше это стоит. Если таблица имеет индекс для интересующих столбцов, MySQL может быстро определить позицию для поиска в середине файла данных, не просматривая все данные. Это намного быстрее, чем последовательно читать каждую строку.
Большинство индексов MySQL (PRIMARY KEY, UNIQUE, INDEX и FULLTEXT) хранятся в файлах . Исключение: индексы на типах пространственных данных используют R-деревья; таблицы MEMORY также поддерживают ; InnoDB использует обратные списки для FULLTEXT индексов.
В общем случае индексы используются, как описано в следующих обсуждениях. Характеристики, специфичные для индексов хэш-типа (как используемых в таблицах MEMORY), описаны в разделе 8.3.8 «Сравнение индексов B-деревьев и хэш-индексов».
MySQL использует индексы для следующих операций:
Для быстрого поиска строк, соответствующих условию
WHERE.Для исключения строк из рассмотрения. Если есть выбор между несколькими индексами, MySQL обычно использует индекс, который находит наименьшее количество строк (самый эффективный индекс).
Если таблица имеет индекс с несколькими столбцами, любой лексический префикс индекса может быть использован оптимизатором для поиска строк. Например, если у вас есть индекс из трех столбцов по
(col1, col2, col3), у вас есть возможности поиска по(col1),(col1, col2)и(col1, col2, col3). Более подробная информация в разделе 8.3.5 «Индексы с несколькими столбцами».-
Для извлечения строк из других таблиц при выполнении объединений. MySQL может более эффективно использовать индексы по столбцам, если они объявлены одинакового типа и размера. В этом контексте,
VARCHARиCHARсчитаются одинаковыми, если объявлены одного размера. Например,VARCHAR(10)иCHAR(10)имеют одинаковый размер, ноVARCHAR(10)иCHAR(15)нет.Для сравнений между небинарными строковыми столбцами, оба столбца должны использовать один и тот же набор символов. Например, сравнение столбца
utf8со столбцомlatin1препятствует использованию индекса.Сравнение разнородных столбцов (например, сравнение строкового столбца с временным или числовым) может предотвратить использование индексов, если значения не могут быть непосредственно сравнены без преобразования. Для данного значения, например,
1в числовом столбце, оно может быть равно любому из нескольких значений в строковом столбце, например,'1',' 1','00001'или'01.e1'. Это исключает использование любых индексов для строкового столбца. -
Для нахождения значения
MIN()илиMAX()для конкретного индексированного столбцаkey_col. Это оптимизируется предварительным процессором, который проверяет, используете ли выWHEREна всех ключевых частях, которые появляются передkey_part_N=constantkey_colв индексе. В этом случае MySQL выполняет одно ключевое обращение для каждого значенияMIN()илиMAX()выражения и заменяет его константой. Если все выражения заменены константами, запрос возвращает результат сразу. Например:SELECT MIN(
key_part2),MAX(key_part2) FROMtbl_nameWHEREkey_part1=10; Для сортировки или группировки таблицы, если сортировка или группировка выполняется по лексическому префиксу применимого индекса (например,
ORDER BY). Если все ключевые части следуют заkey_part1,key_part2DESC, ключ читается в обратном порядке. См. раздел 8.2.1.14 «Оптимизация ORDER BY» и раздел 8.2.1.15 «Оптимизация GROUP BY».-
В некоторых случаях запрос может быть оптимизирован для получения значений без обращения к строкам данных. (Индекс, который предоставляет все необходимые результаты для запроса, называется .) Если запрос использует из таблицы только столбцы, включенные в какой-либо индекс, выбранные значения могут быть получены из дерева индекса для большей скорости:
SELECT
key_part3FROMtbl_nameWHEREkey_part1=1
Индексы менее важны для запросов к небольшим таблицам или большим таблицам, где запросы отчетов обрабатывают большинство или все строки. Когда запрос должен получить доступ к большинству строк, последовательное чтение быстрее, чем работа через индекс. Последовательное чтение минимизирует обращения к диску, даже если не все строки нужны для запроса. Подробности см. в разделе 8.2.1.20 «Избегание полных сканирований таблиц».
© 2025 Oracle
Licensed under the GPLv2 License.