|
|
|
Составной индекс в MySQL и WHERE IN ()
|
|||
|---|---|---|---|
|
#18+
Здравствуйте. Помогите понять. Есть таблица 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. Так? Я всё правильно понимаю? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.08.2016, 08:23 |
|
||
|
Составной индекс в MySQL и WHERE IN ()
|
|||
|---|---|---|---|
|
#18+
UNSET, Для составных индексов смотрите в key_len - здесь обозначается, какую именно часть индекса планировщик хочет использовать, число в байтах. int - это 4 байта. Значит, если key_len = 16, то планировщик хочет использовать весь col1+col2+col3+col4. Если 4 - только col1. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.08.2016, 08:34 |
|
||
|
Составной индекс в MySQL и WHERE IN ()
|
|||
|---|---|---|---|
|
#18+
Melkij Спасибо, но сама логика же правильная? Т.е. по сути IN не является преградой использовать индекс дальше? Просто движок ещё раз пройдется по другой части индекса. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.08.2016, 09:09 |
|
||
|
Составной индекс в MySQL и WHERE IN ()
|
|||
|---|---|---|---|
|
#18+
UNSETТ.е. по сути IN не является преградой использовать индекс дальше? Индекс может использоваться разными способами - для сканирования и для индексного доступа. Вот для второго случая IN будет "последним" используемым полем, насколько я в курсе. Кроме того, надо указывать точную версию MySQL. Кажется, в версиях 5.6-5.7 были изменения на эту тему. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.08.2016, 11:26 |
|
||
|
Составной индекс в MySQL и WHERE IN ()
|
|||
|---|---|---|---|
|
#18+
miksoft mysql 5.7 EXPLAIN говорит что это так - Using index condition т.е. проходит прямо по индексной таблице несмотря на IN а Melkij посоветовал обратить внимание на key_len, в моем случае он как раз = 16 получается полностью проходит. Я эту тему и создал, что обратил внимание на это, я тоже раньше думал, что после IN индекс перестает работает, но он работает, по крайней мере в mysql 5.7 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.08.2016, 11:37 |
|
||
|
Составной индекс в MySQL и WHERE IN ()
|
|||
|---|---|---|---|
|
#18+
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Так? Я всё правильно понимаю? Нет, неправильно. См. выше. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.08.2016, 12:20 |
|
||
|
Составной индекс в MySQL и WHERE IN ()
|
|||
|---|---|---|---|
|
#18+
UNSET Melkij Спасибо, но сама логика же правильная? Т.е. по сути IN не является преградой использовать индекс дальше? Просто движок ещё раз пройдется по другой части индекса. Не является, но учти, что эффективно для всех вариантов сочетаний условий генерируется одно позиционирование по индексу. Код: sql 1. 2. 3. 4. даёт 1*3*2=6 вариантов позиционирования, которые надо проверить. Т.е. эффективность использования индекса для запроса как бы снижается в 6 раз, поэтому в итоге может быть принято решение, что индекс лучше в данном случае не использовать. Чем больше будет значений в IN, тем больше будет вариантов, и тем менее эффективен будет индекс для данного запроса. Но учти, что при этом при больших таблицах и хорошей селективности индекса всё же индекс может использоваться. При этом всём в вышеописанном нет практически никакой специфики MySQL. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.08.2016, 13:04 |
|
||
|
|

start [/forum/topic.php?fid=47&fpage=93&tid=1831460]: |
0ms |
get settings: |
8ms |
get forum list: |
19ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
64ms |
get topic data: |
11ms |
get forum data: |
2ms |
get page messages: |
42ms |
get tp. blocked users: |
1ms |
| others: | 217ms |
| total: | 372ms |

| 0 / 0 |
