MySQL индексы и порядок - PullRequest
30 голосов
/ 10 августа 2009

Это вопрос, который у меня был всегда.

Насколько я знаю, порядок индексов имеет значение. Таким образом, индекс типа [first_name, last_name] не совпадает с [last_name, first_name], верно?

Если я определяю только первый индекс, значит ли это, что он будет использоваться только для

SELECT * FROM table WHERE first_name="john" AND  last_name="doe"; 

а не для

SELECT * FROM table WHERE  last_name="doe" AND first_name="john";

Поскольку я использую ORM, я понятия не имею, в каком порядке будут вызываться эти столбцы. Означает ли это, что я должен добавить индексы для всех перестановок? Это выполнимо, если у меня есть индекс с 2 столбцами, но что произойдет, если мой индекс будет на 3 или 4 столбцах?

Ответы [ 3 ]

47 голосов
/ 10 августа 2009

Порядок индекса имеет значение, когда условия вашего запроса применяются только к PART индекса. Рассмотрим:

  1. SELECT * FROM table WHERE first_name="john" AND last_name="doe"

  2. SELECT * FROM table WHERE first_name="john"

  3. SELECT * FROM table WHERE last_name="doe"

Если ваш индекс (first_name, last_name), запросы 1 и 2 будут его использовать, запрос № 3 - нет. Если ваш индекс (last_name, first_name), запросы 1 и 3 будут использовать его, запрос № 2 - нет. Изменение порядка условий в предложении WHERE не действует ни в одном из случаев.

Подробности здесь

Обновление
В случае, если вышесказанное неясно - MySQL может использовать индекс только в том случае, если столбцы в условиях запроса образуют самый левый префикс индекса. В приведенном выше запросе № 2 нельзя использовать индекс (last_name, first_name), поскольку он основан только на first_name, а first_name НЕ является крайним левым префиксом индекса (last_name, first_name).

Порядок условий в запросе не имеет значения; запрос № 1 выше сможет использовать индекс (last_name, first_name) очень хорошо, потому что его условия равны first_name и last_name и, вместе взятые, они образуют самый левый префикс (last_name, *) 1048 *) индекс.

5 голосов
/ 10 августа 2009

ChssPly76 правильно, что порядок логических выражений не должен совпадать с порядком столбцов в индексе. Булевы операторы коммутативны , а оптимизатор MySQL достаточно умен, чтобы знать, как сопоставить выражение с индексом в большинстве случаев.

Я также хочу добавить, что вы должны научиться использовать функцию EXPLAIN в MySQL, чтобы вы могли сами убедиться, какие индексы оптимизатор выберет для данного запроса.

2 голосов
/ 06 апреля 2014

Почему бы не расширить ответ, чтобы сразу сделать все совершенно прозрачным.

Если таблица имеет индекс из нескольких столбцов, любой крайний левый префикс индекса может использоваться оптимизатором для поиска строк. Например, если у вас есть индекс из трех столбцов на (col1, col2, col3), вы индексировали возможности поиска на (col1), (col1, col2) и (col1, col2, col3).

MySQL не может использовать индекс, если столбцы не образуют крайний левый префикс индекса. Предположим, что у вас есть операторы SELECT, показанные здесь:

SELECT * FROM tbl_name WHERE col1=val1;
SELECT * FROM tbl_name WHERE col1=val1 AND col2=val2;

SELECT * FROM tbl_name WHERE col2=val2;
SELECT * FROM tbl_name WHERE col2=val2 AND col3=val3;

Если для (col1, col2, col3) существует индекс, индекс используют только первые два запроса. Третий и четвертый запросы включают индексированные столбцы, но (col2) и (col2, col3) не являются самыми левыми префиксами (col1, col2, col3). - MySQL dev

...