Прежде чем перейти в режим преждевременная оптимизация , может быть полезно взглянуть на следующий шаблон запроса. Если ничто иное не может быть использовано в качестве базового уровня, по которому можно измерить эффективность возможных оптимизаций.
SELECT T.Tagid, TagInfo.TagName, COUNT(*)
FROM Items I
JOIN Tags TagInfo ON TagInfo.TagId = T.TagId
JOIN ItemTagMap T ON I.ItemId = T.ItemId
--JOIN ItemTagMap T1 ON I.ItemId = T1.ItemId
WHERE I.ItemId IN
(
SELECT ItemId
FROM Items
WHERE -- Some typical initial search criteria
Title LIKE 'Bug Report%' -- Or some fulltext filter instead...
AND ItemDate > '02/22/2008'
AND Status = 'C'
)
--AND T1.TagId = 'MySql'
GROUP BY T.TagId, TagInfo.TagName
ORDER BY COUNT(*) DESC
Подзапрос - это «запрос на вождение», то есть тот, который соответствует начальным критериям конечного пользователя. (подробности о том, как этот запрос, требуемый несколько раз, может вписаться в общий оптимизированный поток, см. ниже)
Прокомментировано соединение на T1 (и, возможно, T2, T3, когда выбрано несколько тегов), и, с предложением WHERE, соответствующие критерии. Они необходимы, когда пользователь выбирает определенный тег, как в рамках начального поиска, так и путем уточнения. (Это может быть более эффективным, чтобы разместить эти объединения и где предложения внутри подзапроса; подробнее об этом ниже)
Обсуждение ...
«Управляющий запрос» или его разновидность необходимы для двух разных целей:
1 для предоставления полного списка ItemId, который необходим для перечисления всех связанных тегов.
2 для предоставления первых N значений ItemId (N - размер отображаемой страницы) для поиска подробной информации об элементе в таблице Item.
Обратите внимание, что полный список не нужно сортировать (или он может выиграть от сортировки в другом порядке), поэтому второй список нужно сортировать по выбору пользователя (скажем, по дате, по убыванию или по названию). в алфавитном порядке по возрастанию). Также обратите внимание, что если требуется какой-либо порядок сортировки, стоимость запроса будет подразумевать работу с полным списком (не допускает нечетной оптимизации самим SQL и / или некоторой денормализации, SQL должен «увидеть» последние записи в этом списке). в случае, если они принадлежат к вершине, в порядке сортировки).
Этот последний факт говорит о том, что для обеих целей используется один и тот же запрос, соответствующий список может быть сохранен во временной таблице. Общий процесс будет состоять в том, чтобы быстро найти верхние записи N Item с их деталями и сразу же вернуть их в приложение. Затем приложение может получить ajax-fashion список тегов для уточнений. Этот список будет создан с запросом, похожим на приведенный выше, где подзапрос заменяется на «select * from временная таблица». Хорошие шансы, что оптимизатор SQL решит отсортировать этот список (в некоторых случаях), давайте позволим ему это сделать, вместо того, чтобы угадывать его и сортировать его явно.
Еще один момент, который следует рассмотреть, - это, возможно, включить объединение (я) в таблицу ItemTagMap в «запрос на вождение», а не так, как показано выше. Вероятно, это лучше всего сделать как с точки зрения производительности, так и потому, что он создаст правильный список для цели № 2 (отображение страницы элементов).
Запрос / поток, описанный выше, вероятно, будет достаточно хорошо масштабироваться даже на относительно скромном оборудовании; ориентировочно на 1/2 миллиона + предметов, при длительном поиске пользователей может быть до 10 в секунду. Одним из ключевых факторов будет селективность начальных критериев поиска.
Идеи оптимизации
- [В зависимости от типичных случаев поиска и статистики данных] может иметь смысл денормализовать путем переноса (даже дублирования) некоторых полей элементов в таблицу ItemTagMap. Короткие поля, в частности, могут быть там «желанными».
- Поскольку данные растут в миллионах элементов, мы можем использовать типично сильную корреляцию некоторых тегов (например, в SO PHP часто поставляется с MySql, кстати, без веской причины ...), с различными приемами. Например, введение тегов «multi-Tag» может сделать логику ввода более сложной, но также может значительно уменьшить размер карты.
- грубо сказал! -
Соответствующая архитектура и оптимизации должны быть выбраны с учетом фактических требований и эффективного статистического профиля данных ...