Better
select col1, col2,col3
from table_name
where col1 = 'x'
and col3 = 'y'
order by col4
limit 3;
Оптимальный индекс - один из следующих:
INDEX(col1, col3, col4)
INDEX(col3, col1, col4)
В обоих случаях оптимизатор может полностью разрешить WHERE
и выполнить ORDER BY
и даже остановиться после 3 строк из-за LIMIT
.
Наилучшее. Еще лучшую производительность можно получить, если добавить col2
к end того или другого. Это делает его индексом «покрытия», поэтому всю работу можно выполнять в BTree индекса, не касаясь BTree данных.
Вернуться к вашему вопросу
Если у вас нет одного из этих индексов, оптимизатор находится в затруднительном положении и часто выбирает неправильный из двух вероятных вариантов. Допустим, у вас есть только
INDEX(col1), INDEX(col4)
План A фокусируется на фильтрации: используйте col1
, но перед тем, как снимать с него, нужно отсортировать все подходящие строки. Но может получиться миллион строк и их придется отсортировать.
План B избегает сортировки: отсканируйте индекс в порядке col4
. Если вам действительно повезет, первые 3 строки будут соответствовать предложению WHERE
. Если это действительно не повезло, он просканирует всю таблицу, не найдя 3 приемлемых строк. Но они будут отсортированы!
«Статистика» скудна и не может реально сделать выбор между двумя вариантами.
Любой план может быть очень медленным.
Аналогичные проблемы возникают с JOINs
при фильтрации предложений WHERE
в обеих таблицах.