Я хочу реализовать очень распространенную функцию - фильтрацию некоторых элементов по тегам. В Интернете есть много учебных пособий с примерами того, как это сделать. Запрос довольно простой и быстрый (при условии наличия правильных индексов).
Но обычно отфильтрованные элементы должны быть отсортированы по некоторому полю. Например, когда вы фильтруете вопросы по тегу в SO, результаты сортируются.
Чтобы выполнить эту задачу (при условии, что нам нужно отсортировать по рейтингу), можно написать:
SELECT item.id FROM item
INNER JOIN taggeditem ON taggeditem.item_id = item.id
WHERE
taggeditem.tag_id = 1234
ORDER BY item.rating DESC
У нас есть индексы (taggeditem.tag_id)
, (item.id)
, (item.rating
)
Проблема с этим запросом состоит в том, что mysql не может использовать индекс для item.rating, потому что ключ, используемый для выборки строк, не совпадает с ключом, используемым в ORDER BY ( MySQL: ORDER BY Optimization ). Это приводит к использованию временной таблицы и сортировки файлов, что, в свою очередь, приводит к медленному времени выполнения.
Решение, которое я нашел, заключается в денормализации поля сортировки в таблицу taggeditem
, чтобы я мог создать индекс (tag_id, item_rating)
для taggeditem
.
Я искал похожие вопросы в SO и нашел только один: Mysql медленный запрос: INNER JOIN + ORDER BY вызывает сортировку файлов . Решение было таким же.
Итак, я хочу спросить, это общее решение этой проблемы? Является ли хорошей практикой денормализация группы полей сортировки в тегированный элемент, например, созданный, рейтинг? В SO вы можете сортировать, используя 4 различных параметра (самые новые, горячие, голоса, активные) - означает ли это, что они денормализованы поля, которые используются для сортировки результатов?
Есть ли альтернативы этому решению?