Я хочу реализовать очень распространенную функцию - фильтрацию некоторых элементов по тегу. В Интернете есть много учебных пособий с примерами того, как это сделать. Запрос довольно прост и быстр (при условии наличия соответствующих индексов).
Но обычно отфильтрованные элементы нужно сортировать по некоторому полю. Например, когда вы фильтруете вопросы по тегу на 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 не может используйте индекс index.rating, потому что ключ, используемый для извлечения строк, не совпадает с ключом, используемым в ORDER BY (MySQL: ORDER BY Optimization). Это приводит к использованию временной таблицы и filesort, что, в свою очередь, приводит к медленному времени выполнения.
Решение, с которым я столкнулся, состоит в том, чтобы денормализовать поле сортировки в таблице taggeditem
, чтобы я мог создать индекс (tag_id, item_rating)
по адресу taggeditem
.
Я искал аналогичные вопросы в SO, и нашел только этот: Mysql slow query: INNER JOIN + ORDER BY causes filesort. Решение было таким же.
Итак, я хочу спросить, это общее решение этой проблемы? Является ли хорошей практикой денормализовать кучу полей сортировки для taggeditem, таких как созданный, рейтинг? В SO вы можете сортировать по 4 различным параметрам (новейшим, горячим, голосам, активным) - означает ли это, что они денормализовали поля, которые используются для сортировки результатов? Есть ли альтернативы этому решению?
это товар или изделие? путайте ... вам может потребоваться повторная проверка SQL – ajreal 2010-11-28 22:09:05
Я отредактировал SQL, я имел в виду элемент таблицы, конечно, – 2010-11-29 05:34:27