Обычно я создаю планы планов, сначала создав запрос, использующий правильный план, и скопировав его в аналогичный запрос, который этого не делает. Однако иногда это бывает сложно, особенно если запрос не совсем такой же. Какой правильный способ создания плановых руководств с нуля?
SQLKiwi упомянул составление планов в SSIS, есть ли способ или полезный инструмент, помогающий составить хороший план для SQL Server?
Конкретный рассматриваемый экземпляр - это CTE: SQLFiddle
with cte(guid,other) as (
select newid(),1 union all
select newid(),2 union all
select newid(),3)
select a.guid, a.other, b.guid guidb, b.other otherb
from cte a
cross join cte b
order by a.other, b.other;
Есть ли ЛЮБОЙ способ заставить результат получить ровно 3 разных guid
с и не более? Я надеюсь, что смогу лучше ответить на вопросы в будущем, включив руководства плана с запросами типа CTE, на которые ссылаются несколько раз, чтобы преодолеть некоторые причуды SQL Server CTE.
sql-server
t-sql
cte
孔夫子
источник
источник
Ответы:
Не сегодня. Нерекурсивные общие табличные выражения (CTE) обрабатываются как определения в виде встроенного представления и раскрываются в логическое дерево запросов в каждом месте, на которое они ссылаются (как и в определениях обычного представления) перед оптимизацией. Логическое дерево для вашего запроса:
Обратите внимание на две привязки вида и шесть вызовов встроенной функции
newid
до начала оптимизации. Тем не менее, многие считают, что оптимизатор должен быть в состоянии определить, что расширенные поддеревья изначально были единым объектом, на который ссылаются, и соответственно упростить. Также было несколько запросов Connect, чтобы разрешить явную материализацию CTE или производной таблицы.В более общей реализации оптимизатор может рассмотреть возможность материализации произвольных общих выражений для повышения производительности (
CASE
с помощью подзапроса это еще один пример, где проблемы могут возникнуть сегодня). Microsoft Research опубликовала документ (PDF) по этому вопросу еще в 2007 году, хотя до сих пор он не реализован. В настоящее время мы ограничены явной материализацией с использованием таких вещей, как переменные таблиц и временные таблицы.Это было просто желаемое размышление с моей стороны, и оно выходило далеко за рамки идеи изменения руководств плана. В принципе, можно написать инструмент для непосредственного управления XML-планом show plan, но без специального инструментария оптимизатора использование этого инструмента, вероятно, будет разочаровывающим опытом для пользователя (и разработчик придет к этому думать).
В конкретном контексте этого вопроса такой инструмент по-прежнему не сможет материализовать содержимое CTE таким образом, который мог бы использоваться несколькими потребителями (в этом случае для подачи обоих входных данных в перекрестное соединение). Оптимизатор и механизм выполнения поддерживают многопользовательские очереди, но только для определенных целей - ни одна из которых не может быть применена к этому конкретному примеру.
Здесь есть достаточная гибкость. Широкая форма плана XML используется для руководства поиском окончательного плана (хотя многие атрибуты полностью игнорируются, например, тип разделения на биржах), и обычные правила поиска также значительно ослаблены. Например, раннее сокращение альтернатив, основанное на соображениях стоимости, отключено, явное введение перекрестных объединений разрешено, а скалярные операции игнорируются.
Слишком много подробностей, чтобы углубиться в них, но размещение фильтров и вычислительных скаляров не может быть принудительным, а предикаты формы
column = value
обобщены, поэтому план содержитX = 1
илиX = @X
может быть применен к запросу, содержащемуX = 502
илиX = @Y
. Эта особая гибкость может очень помочь в нахождении естественного плана силы.В конкретном примере константа Union All всегда может быть реализована как постоянное сканирование; количество входов в Союз All не имеет значения.
источник
Невозможно (версии SQL Server до 2012 г.) повторно использовать одну катушку для обоих вхождений CTE. Подробности можно найти в ответе SQLKiwi. Далее ниже приведены два способа материализации CTE дважды, что неизбежно для характера запроса. Оба варианта приводят к чистому различному количеству guid 6.
Ссылка из комментария Мартина на сайт Quassnoi в блоге о плане управления CTE была частичным вдохновением для этого вопроса. Он описывает способ материализации CTE для целей коррелированного подзапроса, на который ссылается только один раз, хотя корреляция может привести к тому, что он будет оцениваться несколько раз. Это не относится к запросу в вопросе.
Вариант 1 - План руководства
Взяв подсказки из ответа SQLKiwi, я сократил руководство до минимума, который все еще будет выполнять свою работу, например,
ConstantScan
узлы перечисляют только 2 скалярных оператора, которые могут достаточно расшириться до любого числа.Вариант 2 - Удаленное сканирование
Увеличивая стоимость запроса и внедряя удаленное сканирование, результат материализуется.
источник
На полном серьезе вы не можете сократить планы выполнения XML с нуля. Создание их с помощью SSIS - научная фантастика. Да, это все XML, но они из разных вселенных. Глядя на блог Пола на эту тему , он говорит «многое из того, что позволяет SSIS ...», так что, возможно, вы неправильно поняли? Я не думаю, что он говорит "использовать SSIS для создания планов", а скорее "не было бы замечательно иметь возможность создавать планы с использованием интерфейса перетаскивания, такого как SSIS". Возможно, для очень простого запроса вы могли бы просто справиться с этим, но это растянуто, возможно, даже пустая трата времени. Вы можете сказать, что заняты работой.
Если я создаю план для подсказки или руководства плана USE PLAN, у меня есть пара подходов. Например, я мог бы удалить записи из таблиц (например, в копии БД), чтобы повлиять на статистику и призвать оптимизатор принять другое решение. Я также использовал переменные таблицы вместо всей таблицы в запросе, поэтому оптимизатор считает, что каждая таблица содержит 1 запись. Затем в сгенерированном плане замените все переменные таблицы на исходные имена таблиц и замените их как план. Другим вариантом будет использование опции WITH STATS_STREAM в UPDATE STATISTICS для подмены статистики, которая используется при клонировании копий баз данных, содержащих только статистику, например
В прошлом я потратил некоторое время, работая с планами выполнения XML, и обнаружил, что в итоге SQL просто говорит: «Я не использую это» и в любом случае выполняет запрос так, как хочет.
Для вашего конкретного примера, я уверен, вы знаете, что вы можете использовать setcount 3 или TOP 3 в запросе, чтобы получить этот результат, но я думаю, что это не ваша точка зрения. Правильный ответ будет действительно: использовать временную таблицу. Я бы сказал, что:) Неправильный ответ: «потратить часы, даже дни, нарезая свой собственный план выполнения XML, в котором вы пытаетесь обмануть оптимизатора в создании ленивой катушки для CTE, которая может даже не работать, выглядела бы умно» но также было бы невозможно поддерживать ".
Не пытаясь быть неконструктивным, просто мое мнение - надеюсь, это поможет.
источник
Наконец в SQL 2016 CTP 3.0 есть способ, вроде:)
Используя флаг трассировки и Расширенные события, подробно описанные здесь Дмитрием Пилугиным , вы можете (несколько произвольно) найти три уникальных руководства из промежуточных этапов выполнения запроса.
NB. Этот код НЕ предназначен для производственного или серьезного использования в отношении форсирования плана CTE, просто беззаботного взгляда на новый флаг трассировки и другого способа выполнения действий:
Проверено на версии (CTP3.2) - 13.0.900.73 (x64), просто для удовольствия.
источник
Я обнаружил, что traceflag 8649 (план принудительного параллелизма) вызвал такое поведение для левой колонки guid в моих экземплярах 2008, R2 и 2012. Мне не нужно было использовать флаг в SQL 2005, где CTE вел себя правильно. Я попытался использовать план, сгенерированный в SQL 2005, в более высоких экземплярах, но он не прошел проверку.
Либо с помощью подсказки, с помощью руководства плана, включая подсказку, либо с помощью плана, сгенерированного запросом с подсказкой в USE PLAN и т. Д., Все работало.
источник