Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Составной индекс в MySQL и WHERE IN () / 8 сообщений из 8, страница 1 из 1
29.08.2016, 08:23
    #39299323
UNSET
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Составной индекс в MySQL и WHERE IN ()
Здравствуйте. Помогите понять.

Есть таблица tab: id(int) + col1(int) + col2(int) + col3(int) + col4(int)

есть составной индекс COL :col1+col2+col3+col4

и вот такой запрос:

SELECT *
FROM tab
WHERE
col1 IN (1,6,9) AND
col2=54 AND
col3 IN (0,1) AND
col4=5

Правильно ли я понимаю, что здесь полностью используется индекс COL ? Несмотря на IN mysql просто еще раз обходит по индексу.

EXPLAIN вроде говорит что это так - Using index conditionи показывает точно число строк.

А вот если б было:

SELECT *
FROM tab
WHERE
col1>0 AND
col2=54 AND
col3 IN (0,1) AND
col4=5

то индекс бы не использовался после col1.

Так? Я всё правильно понимаю?
...
Рейтинг: 0 / 0
29.08.2016, 08:34
    #39299331
Melkij
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Составной индекс в MySQL и WHERE IN ()
UNSET,

Для составных индексов смотрите в key_len - здесь обозначается, какую именно часть индекса планировщик хочет использовать, число в байтах.
int - это 4 байта. Значит, если key_len = 16, то планировщик хочет использовать весь col1+col2+col3+col4. Если 4 - только col1.
...
Рейтинг: 0 / 0
29.08.2016, 09:09
    #39299341
UNSET
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Составной индекс в MySQL и WHERE IN ()
Melkij

Спасибо, но сама логика же правильная? Т.е. по сути IN не является преградой использовать индекс дальше? Просто движок ещё раз пройдется по другой части индекса.
...
Рейтинг: 0 / 0
29.08.2016, 11:26
    #39299418
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Составной индекс в MySQL и WHERE IN ()
UNSETТ.е. по сути IN не является преградой использовать индекс дальше?
Индекс может использоваться разными способами - для сканирования и для индексного доступа.
Вот для второго случая IN будет "последним" используемым полем, насколько я в курсе.

Кроме того, надо указывать точную версию MySQL. Кажется, в версиях 5.6-5.7 были изменения на эту тему.
...
Рейтинг: 0 / 0
29.08.2016, 11:37
    #39299429
UNSET
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Составной индекс в MySQL и WHERE IN ()
miksoft
mysql 5.7

EXPLAIN говорит что это так - Using index condition т.е. проходит прямо по индексной таблице несмотря на IN

а Melkij посоветовал обратить внимание на key_len, в моем случае он как раз = 16 получается полностью проходит.

Я эту тему и создал, что обратил внимание на это, я тоже раньше думал, что после IN индекс перестает работает, но он работает, по крайней мере в mysql 5.7
...
Рейтинг: 0 / 0
29.08.2016, 12:20
    #39299458
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Составной индекс в MySQL и WHERE IN ()
UNSETЗдравствуйте. Помогите понять.

Есть таблица tab: id(int) + col1(int) + col2(int) + col3(int) + col4(int)

есть составной индекс COL :col1+col2+col3+col4

и вот такой запрос:

SELECT *
FROM tab
WHERE
col1 IN (1,6,9) AND
col2=54 AND
col3 IN (0,1) AND
col4=5

Правильно ли я понимаю, что здесь полностью используется индекс COL ?


Неправильно. Здесь может быть использован данный индекс.

UNSETНесмотря на IN mysql просто еще раз обходит по индексу.



Это нормально, вполне допустимо. Возможны случаи, когда использование такого индекса для такого запроса неоптимально, или же процессор запросов думает (полагает), что его использование не будет оптимально.



UNSETEXPLAIN вроде говорит что это так - Using index conditionи показывает точно число строк.

А вот если б было:

SELECT *
FROM tab
WHERE
col1>0 AND
col2=54 AND
col3 IN (0,1) AND
col4=5

то индекс бы не использовался после col1.


Для такого запроса индекс может быть использован только для позиционирования в индексе по условию col1>0, и скорее всего,
такая операция не будет оптимальной.

Для боле-менее оптимального использования индекса нужны условия точного равенства на лидирующие поля индекса, чем больше, тем оптимальнее используется индекс. Но даже в этом случае решение, использовать индекс или нет, принимается на основе статистики по распределению данных, и может быть принято не в пользу использования индекса.

UNSETТак? Я всё правильно понимаю?

Нет, неправильно. См. выше.
...
Рейтинг: 0 / 0
29.08.2016, 13:04
    #39299512
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Составной индекс в MySQL и WHERE IN ()
UNSET Melkij

Спасибо, но сама логика же правильная? Т.е. по сути IN не является преградой использовать индекс дальше? Просто движок ещё раз пройдется по другой части индекса.

Не является, но учти, что эффективно для всех вариантов сочетаний условий генерируется одно позиционирование по
индексу.

Код: sql
1.
2.
3.
4.
col1 IN (1,6,9) AND
col2=54 AND
col3 IN (0,1) AND
col4=5



даёт 1*3*2=6 вариантов позиционирования, которые надо проверить.
Т.е. эффективность использования индекса для запроса как бы снижается в 6 раз, поэтому в итоге может быть принято
решение, что индекс лучше в данном случае не использовать.

Чем больше будет значений в IN, тем больше будет вариантов, и тем менее эффективен будет индекс для данного запроса. Но учти, что при этом при больших таблицах и хорошей селективности индекса всё же индекс может использоваться.

При этом всём в вышеописанном нет практически никакой специфики MySQL.
...
Рейтинг: 0 / 0
29.08.2016, 13:56
    #39299568
UNSET
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Составной индекс в MySQL и WHERE IN ()
MasterZiv

Спасибо Вам!
...
Рейтинг: 0 / 0
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Составной индекс в MySQL и WHERE IN () / 8 сообщений из 8, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]