Есть ли ЛЮБОЙ способ заставить результат получить ровно 3 различных руководства и не более? Я надеюсь, что смогу лучше ответить на вопросы в будущем, включив руководства плана с запросами типа CTE, на которые ссылаются несколько раз, чтобы преодолеть некоторые причуды SQL Server CTE.
Не сегодня. Нерекурсивные общие табличные выражения (CTE) обрабатываются как определения в виде встроенного представления и раскрываются в логическое дерево запросов в каждом месте, на которое они ссылаются (как и в определениях обычного представления) перед оптимизацией. Логическое дерево для вашего запроса:
LogOp_OrderByCOL: Union1007 ASC COL: Union1015 ASC
LogOp_Project COL: Union1006 COL: Union1007 COL: Union1014 COL: Union1015
LogOp_Join
LogOp_ViewAnchor
LogOp_UnionAll
LogOp_Project ScaOp_Intrinsic newid, ScaOp_Const
LogOp_Project ScaOp_Intrinsic newid, ScaOp_Const
LogOp_Project ScaOp_Intrinsic newid, ScaOp_Const
LogOp_ViewAnchor
LogOp_UnionAll
LogOp_Project ScaOp_Intrinsic newid, ScaOp_Const
LogOp_Project ScaOp_Intrinsic newid, ScaOp_Const
LogOp_Project ScaOp_Intrinsic newid, ScaOp_Const
Обратите внимание на две привязки вида и шесть вызовов встроенной функции newid
до начала оптимизации. Тем не менее, многие считают, что оптимизатор должен быть в состоянии определить, что расширенные поддеревья изначально были единым объектом, на который ссылаются, и соответственно упростить. Также было несколько запросов Connect, чтобы разрешить явную материализацию CTE или производной таблицы.
В более общей реализации оптимизатор может рассмотреть возможность материализации произвольных общих выражений для повышения производительности ( CASE
с помощью подзапроса это еще один пример, где проблемы могут возникнуть сегодня). Microsoft Research опубликовала документ (PDF) по этому вопросу еще в 2007 году, хотя до сих пор он не реализован. В настоящее время мы ограничены явной материализацией с использованием таких вещей, как переменные таблиц и временные таблицы.
SQLKiwi упомянул составление планов в SSIS, есть ли способ или полезный инструмент, помогающий составить хороший план для SQL Server?
Это было просто желаемое размышление с моей стороны, и оно выходило далеко за рамки идеи изменения руководств плана. В принципе, можно написать инструмент для непосредственного управления XML-планом show plan, но без специального инструментария оптимизатора использование этого инструмента, вероятно, будет разочаровывающим опытом для пользователя (и разработчик придет к этому думать).
В конкретном контексте этого вопроса такой инструмент по-прежнему не сможет материализовать содержимое CTE таким образом, который мог бы использоваться несколькими потребителями (в этом случае для подачи обоих входных данных в перекрестное соединение). Оптимизатор и механизм выполнения поддерживают многопользовательские очереди, но только для определенных целей - ни одна из которых не может быть применена к этому конкретному примеру.
Хотя я не уверен, у меня есть довольно сильное предчувствие, что RelOps могут соблюдаться (Nested Loop, Lazy Spool), даже если запрос не совпадает с планом - например, если вы добавили 4 и 5 в CTE , он все еще продолжает использовать тот же план (по-видимому - проверено на SQL Server 2012 RTM Express).
Здесь есть достаточная гибкость. Широкая форма плана XML используется для руководства поиском окончательного плана (хотя многие атрибуты полностью игнорируются, например, тип разделения на биржах), и обычные правила поиска также значительно ослаблены. Например, раннее сокращение альтернатив, основанное на соображениях стоимости, отключено, явное введение перекрестных объединений разрешено, а скалярные операции игнорируются.
Слишком много подробностей, чтобы углубиться в них, но размещение фильтров и вычислительных скаляров не может быть принудительным, а предикаты формы column = value
обобщены, поэтому план содержит X = 1
или X = @X
может быть применен к запросу, содержащему X = 502
или X = @Y
. Эта особая гибкость может очень помочь в нахождении естественного плана силы.
В конкретном примере константа Union All всегда может быть реализована как постоянное сканирование; количество входов в Союз All не имеет значения.