2017-01-10 2 views
1

Я пытаюсь оптимизировать этот запрос:Мой индекс нескольких столбцов не используется запрос

select id, entity_type 
from tv_classified 
where entity_type != 2 
    and state = 0 
    and dateExpiration < now(); 

54630 rows in set (1 min 0.42 sec) 

Так я добавил индекс по этим столбцам:

CREATE INDEX full_expiration_idx ON tv_classified (entity_type, state, dateExpiration) 

Проблема заключается в том, что мой запрос по-прежнему занимает то же самое время, и игнорировать индекс:

explain select id, entity_type from tv_classified where entity_type != 2 and state = 0 and dateExpiration < now(); 
+----+-------------+---------------+------+------------------------------------------------------------------+-----------+---------+-------+---------+-------------+ 
| id | select_type | table   | type | possible_keys             | key  | key_len | ref | rows | Extra  | 
+----+-------------+---------------+------+------------------------------------------------------------------+-----------+---------+-------+---------+-------------+ 
| 1 | SIMPLE  | tv_classified | ref | dateExpiration_idx,entity_type_idx,state_idx,full_expiration_idx | state_idx | 2  | const | 1483498 | Using where | 
+----+-------------+---------------+------+------------------------------------------------------------------+-----------+---------+-------+---------+-------------+ 

кажется, что Mysql не использует этот индекс и предпочитают использовать I ndex в поле «state».

Я знаю, что могу использовать use index(full_expiration_idx) в запросе (и он работает быстро 1мин -> 0,5 с), но я хотел бы понять, почему Mysql не использует его сам.

С уважением,

+1

Я не знаю, но у меня есть инстинкт кишки о '! ='. Можете ли вы рассказать нам (вне интереса), используется ли индекс, если вы попробуете его с помощью 'entity_type = 2' вместо этого? Я понимаю, что это не то, что вы хотите сделать, но это может подтвердить то, что я думаю. –

+0

@LightnessRacesinOrbit Хороший вызов, хороший индекс выбирается, если я изменяю '! = 2' с' IN (0, 1, 3, 4) ', вы знаете, почему? –

+0

Я думаю, это потому, что у вас нет «известного диапазона» в самой левой части ключа. Если вы представляете, как структурированы сами индексные данные, MySQL не может просто выполнить поиск в 'entity_type', затем поиск на' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '', тогда, наконец, поиск диапазона на 'dateExpiration' под этим , Это _could_ с '=', но с вашим '! =' Вместо этого нужно искать почти все листы дерева 'entity_type' (фактически, буквально все из них, кроме одного), и поэтому преимущество поиска индекса на самом деле нет. Решено, что без него лучше. –

ответ

0

Вы создали составной ключ, который может быть использован при условии соединения, где ваши 3 колонки вместе с 3 столбцами другой таблицы. Так как вы используете фильтрованное условие, создайте 3 отдельных индекса для 3 столбцов.

+0

Составной индекс часто _great_ для цепочки условий, но здесь (и я думаю, что это потому, что первое условие - '! =', а не '='), OP должен полагаться на оптимизацию слияния индекса, что действительно нужны отдельные индексы с одним столбцом. Я читаю https://dev.mysql.com/doc/refman/5.7/en/multiple-column-indexes.html и пытается обновить свою память. –

+0

Отказ от ответственности: Я действительно не знаю, что ИМО поможет. –

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