Указание поведения параметризации запросов с помощью руководств по плану

Область применения: SQL Server База данных SQL Azure Управляемый экземпляр SQL Azure

Если задать для параметра базы данных PARAMETERIZATION значение SIMPLE, оптимизатор запросов SQL Server может принять решение о параметризации запросов. Эта параметризация заменяет любые литеральные значения в запросе параметрами. Этот процесс называется простой параметризацией. Если используется параметризация SIMPLE, вы не можете контролировать, какие запросы параметризуются, а какие — нет. Однако можно указать, что все запросы в базе данных будут параметризованы, установив PARAMETERIZATION для параметра базы данных значение FORCED. Этот процесс называется принудительной параметризацией.

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

Option Description
SIMPLE Можно указать, что для определенного класса запросов предпринимается попытка принудительной параметризации. Для этого создайте путеводитель плана TEMPLATE для параметризованной формы запроса и укажите подсказку запроса PARAMETERIZATION FORCED в хранимой процедуре sp_create_plan_guide. Такая разновидность структуры плана представляет собой способ включения принудительной параметризации только для определенного класса запросов, а не для всех. Дополнительные сведения см. в разделе "Простая параметризация".
FORCED Можно указать, что для определенного класса запросов выполняется попытка только простой параметризации, а не принудительной параметризации. Это делается путем создания плана-шаблона TEMPLATE для формы запроса с принудительной параметризацией и указания подсказки запроса PARAMETERIZATION SIMPLE в sp_create_plan_guide. Дополнительные сведения см. в разделе "Принудительное параметризация".

Рассмотрим следующий запрос к базе данных AdventureWorks2025 :

SELECT pi.ProductID,
       SUM(pi.Quantity) AS Total
FROM Production.ProductModel AS pm
     INNER JOIN Production.ProductInventory AS pi
         ON pm.ProductModelID = pi.ProductID
WHERE pi.ProductID = 101
GROUP BY pi.ProductID, pi.Quantity
HAVING SUM(pi.Quantity) > 50;

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

  1. Получить параметризованную форму запроса. Единственным безопасным способом получения этого значения для использования sp_create_plan_guide является использование sp_get_query_template системной хранимой процедуры.

  2. Создайте плановое руководство для параметризованной формы запроса, указав подсказку запроса PARAMETERIZATION FORCED.

    Внимание

    В рамках параметризации запроса SQL Server назначает тип данных параметрам, заменяющим литеральные значения, в зависимости от значения и размера литерала. Тот же процесс применяется к значению литералов-констант, передаваемых в выходной параметр @stmt метода sp_get_query_template. Так как тип данных, указанный в @params аргументеsp_create_plan_guide, должен совпадать с типом запроса, так как он параметризован SQL Server, может потребоваться создать несколько руководств по плану, чтобы охватывать полный диапазон возможных значений параметров для запроса.

Следующий скрипт можно использовать как для получения параметризированного запроса, так и для дальнейшего создания по нему структуры плана:

DECLARE @stmt AS NVARCHAR (MAX);
DECLARE @params AS NVARCHAR (MAX);

EXECUTE sp_get_query_template
    N'SELECT pi.ProductID, SUM(pi.Quantity) AS Total
      FROM Production.ProductModel AS pm
      INNER JOIN Production.ProductInventory AS pi ON pm.ProductModelID = pi.ProductID
      WHERE pi.ProductID = 101
      GROUP BY pi.ProductID, pi.Quantity
      HAVING SUM(pi.Quantity) > 50',
@stmt OUTPUT, @params OUTPUT;

EXECUTE sp_create_plan_guide N'TemplateGuide1',
@stmt, N'TEMPLATE', NULL,
@params, N'OPTION(PARAMETERIZATION FORCED)';

Если для базы данных уже включена принудительная параметризация, ее можно переопределить для отдельных запросов. Чтобы параметризировать пример запроса и синтаксически эквивалентные запросы в соответствии с простыми правилами параметризации, укажите PARAMETERIZATION SIMPLE вместо PARAMETERIZATION FORCED предложения OPTION .

Примечание.

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