Руководства планов

Применяется к:SQL ServerAzure SQL DatabaseAzure, управляемому экземпляру SQL Azure

Руководства по планированию позволяют оптимизировать производительность запросов, если вы не можете или не хотите напрямую изменять текст фактического запроса в SQL Server. Структуры планов влияют на оптимизацию запросов путем присоединения к ним указаний запроса или постоянного плана запроса. Структуры планов полезны, когда небольшое подмножество запросов в приложении базы данных стороннего разработчика выполняются не так, как ожидается. В структуре плана задается инструкция Transact-SQL, которую нужно оптимизировать, и либо предложение OPTION, содержащее указания запросов, либо конкретный план запроса, с помощью которого планируется оптимизировать запрос. При выполнении запроса SQL Server соответствует инструкции Transact-SQL руководству по плану и присоединяет предложение OPTION к запросу во время выполнения или использует указанный план запроса. Так как оптимизатор запросов SQL Server обычно выбирает оптимальный план выполнения для запроса, рекомендуется использовать только руководства по плану в качестве последнего средства для опытных разработчиков и администраторов баз данных.

Заметка

Указания хранилища запросов предоставляют более удобный метод для формирования планов запросов без изменения кода приложения. Указания хранилища запросов проще, чем руководства по плану. Указания хранилища запросов доступны в Базе данных SQL Azure и Управляемом экземпляре SQL Azure, а также в SQL Server 2022 (16.x) и более поздних версиях.

Общее число структур планов, которые можно создать, ограничивается только доступными системными ресурсами. Тем не менее использование структур планов должно быть ограничено критически важными запросами, затрагиваемыми в целях улучшения или стабилизации производительности. Структуры планов не следует использовать для основной массы запросов развернутого приложения.

Полученный при применении этой возможности план выполнения будет таким же, как принудительно применяемый план, или очень близким к нему. Так как итоговый план может не совпадать с планом, указанным в структуре плана, производительность этих планов может различаться. В редких случаях возможна значительная негативная разница в производительности, и тогда администратору следует удалить принудительный план.

Руководства по планированию нельзя использовать в каждом выпуске Microsoft SQL Server. Сведения о функциях, поддерживаемых различными выпусками SQL Server, см. в статье Возможности, поддерживаемые выпусками SQL Server 2016. Структуры планов видны в любом выпуске. Можно также присоединить базу данных, содержащую структуры планов, к любой версии. Руководства по планированию остаются неизменными при восстановлении или присоединении базы данных к обновленной версии SQL Server.

Типы структур планов

Могут быть созданы структуры планов следующих типов.

OBJECT, руководство плана

Структура плана OBJECT соответствует запросам, выполняемым в контексте хранимых процедур Transact-SQL, определяемых пользователем скалярных функций, определяемых пользователем функций с несколькими инструкциями, возвращающих табличные значения, и триггеров DML.

Предположим, что следующая хранимая процедура, которая принимает параметр @Country_region, относится к приложению базы данных, которое развертывается в связи с базой данных AdventureWorks2022.

CREATE PROCEDURE Sales.GetSalesOrderByCountry (@Country_region nvarchar(60))  
AS  
BEGIN  
    SELECT *  
    FROM Sales.SalesOrderHeader AS h, Sales.Customer AS c,   
        Sales.SalesTerritory AS t  
    WHERE h.CustomerID = c.CustomerID  
        AND c.TerritoryID = t.TerritoryID  
        AND CountryRegionCode = @Country_region  
END;  

Предположим, что эта хранимая процедура была скомпилирована и оптимизирована для @Country_region = N'AU' (Австралия). Тем не менее, поскольку существует относительно мало заказов на продажу, поступающих из Австралии, производительность уменьшается при выполнении запроса с использованием значений параметров стран или регионов с большим количеством заказов на продажу. Так как страна, из которой поступает больше всего заказов на продажу, — США, план запроса, сформированный для значения @Country_region = N'US' , вероятно, обеспечит лучшую производительность для всех возможных значений параметра @Country_region .

Чтобы решить эту проблему, измените хранимую процедуру и добавьте указание OPTIMIZE FOR в запрос. Однако так как хранимая процедура находится в развернутом приложении, напрямую менять код приложения нельзя. Вместо этого можно создать следующую структуру плана в базе данных AdventureWorks2022 .

sp_create_plan_guide   
@name = N'Guide1',  
@stmt = N'SELECT *FROM Sales.SalesOrderHeader AS h,  
        Sales.Customer AS c,  
        Sales.SalesTerritory AS t  
        WHERE h.CustomerID = c.CustomerID   
            AND c.TerritoryID = t.TerritoryID  
            AND CountryRegionCode = @Country_region',  
@type = N'OBJECT',  
@module_or_batch = N'Sales.GetSalesOrderByCountry',  
@params = NULL,  
@hints = N'OPTION (OPTIMIZE FOR (@Country_region = N''US''))';  

При выполнении запроса, указанного в инструкции sp_create_plan_guide , этот запрос изменяется до оптимизации: в него добавляется предложение OPTIMIZE FOR (@Country = N''US'') .

Структура плана SQL

Структура плана SQL соответствует запросам, выполняющимся в контексте изолированных инструкций и пакетов Transact-SQL, не входящих ни в один объект базы данных. Структуры планов SQL также можно использовать для соответствия запросам с параметрами. Структуры планов SQL применяются к изолированным инструкциям и пакетам Transact-SQL. Часто эти инструкции передаются приложением с помощью хранимой процедуры sp_executesql . Например, рассмотрим следующий изолированный пакет:

SELECT TOP 1 * FROM Sales.SalesOrderHeader ORDER BY OrderDate DESC;  

Чтобы избежать создания параллельного плана выполнения для этого запроса, создайте приведенную ниже структуру плана и присвойте указанию запроса MAXDOP значение 1 в параметре @hints .

sp_create_plan_guide   
@name = N'Guide2',   
@stmt = N'SELECT TOP 1 * FROM Sales.SalesOrderHeader ORDER BY OrderDate DESC',  
@type = N'SQL',  
@module_or_batch = NULL,   
@params = NULL,   
@hints = N'OPTION (MAXDOP 1)';  

В качестве другого примера рассмотрим следующую инструкцию SQL, отправленную с помощью sp_executesql.

exec sp_executesql N'SELECT * FROM Sales.SalesOrderHeader
where SalesOrderID =  @so_id', N'@so_id int', @so_id = 43662;  

Чтобы создать уникальный план для каждого выполнения этого запроса, создайте следующую структуру плана и используйте указание запроса OPTION (RECOMPILE) в параметре @hints.

exec sp_create_plan_guide   
@name = N'PlanGuide1_SalesOrders',   
@stmt = N'SELECT * FROM Sales.SalesOrderHeader
where SalesOrderID =  @so_id',
@type = N'SQL',  
@module_or_batch = NULL,   
@params = N'@so_id int',   
@hints = N'OPTION (recompile)';

Внимание

Значения, передаваемые для аргументов @module_or_batch и @params инструкции sp_create_plan guide , должны соответствовать тексту настоящего запроса. Дополнительные сведения см. в разделах sp_create_plan_guide (Transact-SQL) и Использование SQL Server Profiler для создания и проверки структур планов.

Кроме того, структуры планов SQL можно создавать для запросов с той же параметризованной формой, если значением параметра базы данных PARAMETERIZATION является SET или FORCED либо если создана структура плана TEMPLATE, определяющая, что класс запросов должен быть параметризован.

TEMPLATE, структура плана

Структура плана TEMPLATE соответствует изолированным инструкциям с параметрами. Эти структуры планов используются для замещения текущего параметра PARAMETERIZATION инструкции SET базы данных для класса запросов.

Структуры планов TEMPLATE создаются в одной из следующих ситуаций.

  • Параметр базы данных PARAMETERIZATION установлен равным FORCED, но некоторые запросы желательно скомпилировать в соответствии с правилами простой параметризации.

  • Параметр базы данных PARAMETERIZATION установлен равным SIMPLE (значение по умолчанию), но вы хотите включить принудительную параметризацию для определенного класса запросов.

Требования по соответствию для структур планов

Структуры планов действительны в области видимости базы данных, в которой они создаются. Поэтому с запросом могут быть согласованы только структуры планов, находящиеся в базе данных, которая является текущей при выполнении запроса. Например, если AdventureWorks2022 является текущей базой данных и выполняется нижеследующий запрос:

SELECT FirstName, LastName FROM Person.Person;

Только руководства планов в базе данных AdventureWorks2022 подлежат сопоставлению с этим запросом. Но если AdventureWorks2022 является текущей базой данных и выполняются нижеследующие инструкции:

USE DB1; 
SELECT FirstName, LastName FROM Person.Person;

Для согласования с запросом применимы только структуры планов в DB1 , поскольку запрос выполняется в контексте DB1.

В руководствах по планам на основе SQL или TEMPLATE SQL Server соответствует значениям @module_or_batch и @params аргументам запроса, сравнивая два символа по символам. Это означает, что необходимо указать текст точно так же, как SQL Server получает его в фактическом пакете.

Если @type = "SQL" и @module_or_batch имеет значение NULL, значение @module_or_batch присваивается значению @stmt. Это означает, что значение для statement_text должно быть предоставлено в идентичном формате, символе для символов, как оно отправляется в SQL Server. Для упрощения соответствия формата внутренние преобразования не выполняются.

Если к инструкции могут быть применены и обычная структура плана (SQL или OBJECT), и структура плана TEMPLATE, то используется только обычная структура плана.

Заметка

Пакет, содержащий инструкцию, для которой необходимо создать структуру плана, не может содержать инструкцию USE database .

Влияние структуры плана на кэш планов

Создание структуры плана в модуле стирает план запроса для этого модуля из кэша планов. Создание структуры плана типа OBJECT или SQL в потоке стирает план запроса для потока, который имеет такое же значение хеш-функции. Создание структуры плана типа TEMPLATE стирает все потоки с одним оператором из кэша планов через базу данных.

Задача Раздел
Описано, как создать структуру плана. Создание структуры плана
Описано, как создать структуру плана для параметризованных запросов. Создание структуры плана для параметризованных запросов
Описано, как управлять режимом параметризации запроса с использованием структур планов. Указание механизма параметризации запросов с помощью структур плана
Описано, как включить постоянный план запроса в структуру плана. Применение фиксированного плана запроса к структуре плана
Описано, как задать указания запросов в структуре плана. Присоединение указаний запросов к структуре плана
Описано, как просматривать свойства структуры плана. Просмотр свойств структуры плана
Описано, как использовать профилировщик SQL Server для создания и проверки структур планов. Использование приложения SQL Server Profiler для создания и проверки структур плана
Описано, как проверять структуры планов. Проверка структур плана после обновления

См. также

sp_create_plan_guide (Transact-SQL)
sp_create_plan_guide_from_handle (Transact-SQL)
sp_control_plan_guide (Transact-SQL)
sys.plan_guides (Transact-SQL)
sys.fn_validate_plan_guide (Transact-SQL)