У меня есть запрос, который извлекает 5 записей из таблицы ~ 10000. Предложение order
не распространяется на индекс, но предложение where
равно.
Запрос сканирует около 7 700 строк, чтобы вытащить эти 5 результатов, и это кажется немного большим. Я понимаю, однако, что сложность критериев заказа усложняет ситуацию. Как, если вообще, можно ли уменьшить количество отсканированных строк?
Запрос выглядит следующим образом:
SELECT *
FROM `mediatypes_article`
WHERE `mediatypes_article`.`is_published` = 1
ORDER BY `mediatypes_article`.`published_date` DESC, `mediatypes_article`.`ordering` ASC, `mediatypes_article`.`id` DESC LIMIT 5;
medaitypes_article.is_published
индексируется.
Сколько строк относится к "is_published = 1"? Я предполагаю, что это как... 7.700 строк?
В любом случае вы получите результат полный, который будет соответствовать предложению WHERE, и будет полностью упорядочен по всем критериям сортировки. Затем полный список всех отсортированных опубликованных статей будет усечен после первых 5 результатов.
Возможно, это поможет вам взглянуть на статью о документации по MySQL об оптимизации ORDER BY, но для первого вы должны попытаться применить индексы на столбцах, которые указаны в инструкции ORDER BY. Очень вероятно, что это значительно ускорит процесс.
Когда у вас есть заказ, вам нужно пройти все btree, чтобы выяснить правильный порядок.
10 000 записей на заказ - это не то, что нужно беспокоиться. Помните, что при правильной индексации СУРБД не извлекает всю запись, чтобы выяснить порядок. Он имеет индексированные столбцы на страницах btree, сохраненных на диске и с небольшим количеством просмотров страниц, весь btree загружается в память и может быть пройден.
Выполнение OPTIMIZE TABLE может не помочь, но это тоже не повредит.
В MySQL вы можете создать индекс, содержащий несколько столбцов. Я думаю, что вам, вероятно, нужно сделать, это сделать индекс, который включает is_published и published_date. Вы должны посмотреть результат из инструкции EXPLAIN, чтобы убедиться, что он делает что-то умным способом, и добавьте индекс, если это не так.
EXPLAIN
перед отправленным запросом, запустите его и опубликуйте результаты.