У меня довольно большая таблица (миллионы строк), работающая на MariaDB (InnoDB, 5.5.48-MariaDB-1 ~ precision-wsrep), скажем, моя структура таблицы следующая
[
ID,
Field A,
Field B,
Field C,
Field D
]
У меня есть 3 индекса в этой таблице:
- PRIMARY[ID]
- INDEX 1 -> [A,B,C]
- INDEX 2 -> [A, D]
Запрос, который я пытаюсь оптимизировать, следующий
SELECT * FROM table
WHERE (a = val1) AND (B NOT IN ([val2, val3])) AND (C BETWEEN val4 AND val5)
ORDER BY ID ASC LIMIT 50 OFFSET 100
Этот запрос должен естественно соответствовать моему INDEX 1, верно? Но Мария предпочитает использовать ПЕРВИЧНЫЙ ИНДЕКС, который в основном означает полное сканирование таблицы (в результате чего запросы 40-х годов ...).
Когда я удаляю из этого запроса ORDER или LIMIT (или оба), Maria DB может выбрать INDEX 2, который явно лучше, чем PRIMARY.
Вопрос 1 -> Почему Мария отступает к ПЕРВИЧНОМУ ИНДЕКСУ, когда есть комбинация ORDER BY и LIMIT?
Я решил немного настроить свой запрос, запретив использование ПЕРВИЧНОГО.
SELECT * FROM table IGNORE INDEX(`PRIMARY`)
WHERE (a = val1) AND (B NOT IN ([val2, val3])) AND (C BETWEEN val4 AND val5)
ORDER BY ID ASC LIMIT 50 OFFSET 100
Результат -> Вполне доволен моей первой оптимизацией, этот запрос 40-х годов теперь занимает 1 с, но все же ...
Вопрос 2 -> почему MariaDB выбирает INDEX 2?
Когда я заставляю Марию использовать INDEX 1, запрос падает до 100 мс (в 10 раз быстрее), поэтому я еще не полностью удовлетворен ...
Спасибо за помощь, ребята:)