2009-08-09 2 views
29

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

Насколько я знаю, порядок индексов имеет значение. Таким образом, индекс, такой как [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"; 

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

ответ

44

Индексный вопрос имеет значение, если ваши условия запроса применимы только к ЧАСТЬ указателя. Рассмотрим:

  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 не имеет никакого эффекта в обоих случаях.

Подробности here

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

Порядок условий В ЗАПОЛНЕНИИ запроса не имеет значения; запрос № 1 выше сможет использовать (, first_name) индекс просто отлично, потому что его условия равны first_name и last_name и, вместе взятые, они образуют самый левый префикс (last_name, first_name).

+0

Итак, я думаю, SELECT * FROM table WHERE last_name = "doe" AND first_name = "john" не будет? Если это так, то, поскольку все здание запроса скрыто моим ORM, мне, вероятно, нужно определить 2 индекса ... что действительно отстойно, потому что у меня есть индекс на 3 столбцах, чтобы определить ... –

+1

Нет, вы неправильно поняли. WHERE 'last_name' =" doe "И запрос' first_name' = "john" будет использовать либо ('first_name',' last_name'), либо ('last_name',' first_name') индексы просто отлично. – ChssPly76

+0

Вопрос: для запроса с условием 2 И, имеет ли значение, скорость мудрая, индекс инвертирован по сравнению с условиями в запросе или нет? Или это зависит от мощности этих столбцов? – Mihai

5

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

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

+2

+1 для объяснения. – Petrogad

+0

MySQL Workbench отображает графическое представление информации 'EXPLAIN' в разделе« План выполнения ». –

2

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

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

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

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

Смежные вопросы