Указание механизма параметризации запросов с помощью руководств плана
Если параметр базы данных PARAMETERIZATION установлен инструкцией SET в значение SIMPLE, оптимизатор запросов SQL Server может выбрать параметризацию запросов. Это значит, что все значения-литералы, содержащиеся в запросе, заменяются параметрами. Этот процесс называется простой параметризацией. При применении простой (SIMPLE) параметризации невозможно контролировать, какие запросы параметризуются, а какие нет. Однако можно параметризовать все запросы в базе данных, присвоив параметру базы данных PARAMETERIZATION в инструкции SET значение FORCED. Этот процесс называется принудительной параметризацией.
Механизм параметризации в базе данных можно переопределить с помощью руководств планов следующим путем.
- Если значение параметра базы данных PARAMETERIZATION равно SIMPLE, можно указать, чтобы попытки принудительной параметризации выполнялись в определенном классе запросов. Это можно сделать путем создания руководства плана TEMPLATE для параметризованной формы запроса и указания в запросе подсказки PARAMETERIZATION FORCED с помощью хранимой процедуры sp_create_plan_guide. Такая разновидность руководства плана представляет собой способ включения принудительной параметризации только для определенного класса запросов, а не для всех.
- Если значение параметра базы данных PARAMETERIZATION равно FORCED, можно указать, чтобы для определенного класса запросов выполнялись только попытки простой параметризации вместо принудительной. Это можно сделать путем создания руководства плана TEMPLATE для формы запроса с принудительной параметризацией и указания в запросе подсказки PARAMETERIZATION SIMPLE с помощью хранимой процедуры sp_create_plan_guide.
Рассмотрим следующий запрос к базе данных AdventureWorks:
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;
Администратор базы данных решил не включать принудительную параметризацию для всех запросов к базе данных. Однако необходимо избегать затрат на компиляцию для всех запросов, синтаксически эквивалентных предыдущему и различающихся только значениями констант-литералов. Иными словами, необходимо реализовать параметризацию запроса таким образом, чтобы план для данного вида запроса использовался повторно. В этом случае нужно выполнить следующее.
- Получить параметризованную форму запроса. Единственным безопасным путем получения данного значения для последующего использования в процедуре sp_create_plan_guide является использование системной хранимой процедуры sp_get_query_template.
- Создать руководство плана для параметризованной формы запроса, указав в запросе подсказку PARAMETERIZATION FORCED.
Важно! В ходе параметризации запроса SQL Server присваивает параметрам, заменяющим значения-литералы, определенный тип данных в зависимости от значения и размера литерала. Подобный процесс выполняется и для значений констант-литералов, передаваемых в качестве выходного параметра @stmt процедуры sp_get_query_template. Так как тип данных, указанный в аргументе @params процедуры sp_create_plan_guide, должен соответствовать типу данных в запросе после его параметризации SQL Server, может потребоваться создание нескольких руководств планов для охвата всего диапазона возможных значений параметров запроса. Дополнительные сведения о типах данных, назначаемых SQL Server параметрам после параметризации запроса, см. в разделе Принудительная параметризация.
Следующий сценарий можно использовать как для получения параметризованного запроса, так и для дальнейшего создания по нему руководства плана:
DECLARE @stmt nvarchar(max);
DECLARE @params nvarchar(max);
EXEC 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;
EXEC sp_create_plan_guide
N'TemplateGuide1',
@stmt,
N'TEMPLATE',
NULL,
@params,
N'OPTION(PARAMETERIZATION FORCED)';
Подобным образом в базе данных, в которой уже включена принудительная параметризация, можно гарантировать, что указанный в качестве примера запрос и другие синтаксически ему эквивалентные, в которых различаются только значения констант-литералов, будут параметризованы согласно правилам простой параметризации. Для этого следует указать PARAMETERIZATION SIMPLE вместо PARAMETERIZATION FORCED в предложении OPTION.
Примечание. |
---|
С помощью руководств плана TEMPLATE осуществляется сопоставление инструкций с запросами, поступающими в пакетах, каждый из которых состоит только из одной инструкции. Инструкции, находящиеся в пакетах с несколькими инструкциями, не подлежат сопоставлению с руководствами планов TEMPLATE. |
См. также
Основные понятия
Оптимизация запросов в используемых приложениях с помощью руководств планов