Ответ 1
Пол Уайт подробно объяснил этот "трюк" в своем посте "Настройка производительности всего плана запросов" в разделе Поиск отличительных значений.Почему база данных не может сама выполнить эту оптимизацию?
Является ли рекурсивный CTE полезным для других систем баз данных?
Оптимизатор не идеален и не реализует все возможные методы. Люди попросили Microsoft ее реализовать. См. Этот пункт Connect Внедрение индекса Skip Scan. Он был закрыт, так как Will not Fix, но это не значит, что в будущем он не будет рассмотрен. Другие СУБД могут это реализовать (элемент Connect указывает, что Oracle реализует эту оптимизацию). Если такая оптимизация реализована в СУБД, то этот "трюк" не нужен, и оптимизатор выбирает оптимальный метод вычисления результата на основе доступных статистических данных.
Я не понимаю, почему это ускоряет запрос.
Я не уверен, в каких случаях этот подход выгоден
Простой DISTINCT
запрос сканирует весь индекс. "Сканирование" означает, что он считывает каждую страницу индекса с диска и агрегирует значения в памяти (или tempdb), чтобы получить список различных значений.
Если вы знаете, что в таблице много строк, но только несколько разных различных значений, то чтение всех этих повторяющихся значений является пустой тратой времени. Рекурсивный CTE заставляет сервер искать индекс для первого отдельного значения, затем искать индекс для второго значения и так далее. "Ищите" означает, что сервер использует двоичный поиск в индексе для поиска значения. Обычно для поиска требуется чтение только нескольких страниц с диска. "Индекс" - это сбалансированное дерево.
Если таблица имеет только несколько отдельных значений, она быстрее ищет несколько раз, чем чтение всех страниц индекса. С другой стороны, если есть много разных значений, тогда было бы быстрее читать все страницы последовательно, чем искать для каждого последовательного значения. Это должно дать вам представление о том, в каких случаях этот подход выгоден.
Очевидно, что если таблица мала, ее можно быстрее сканировать. Только когда таблица становится "достаточно большой", вы начинаете видеть разницу в производительности.
Есть вопрос, связанный с dba.se: Можно ли получить параллельный план поиска для отдельной/группы на?