Указание механизма параметризации запросов с помощью структур плана
Если для параметра базы данных PARAMETERIZATION установлено значение SIMPLE, оптимизатор запросов SQL Server может выбрать параметризацию запросов. Это значит, что все литеральные значения, содержащиеся в запросе, заменяются параметрами. Этот процесс называется простой параметризацией. При применении простой (SIMPLE) параметризации невозможно контролировать, какие запросы параметризуются, а какие нет. Однако можно параметризовать все запросы в базе данных, присвоив параметру базы данных PARAMETERIZATION значение FORCED. Этот процесс называется принудительной параметризацией.
Механизм параметризации в базе данных можно переопределить с помощью структур планов следующим путем.
Если значение параметра базы данных PARAMETERIZATION равно SIMPLE, можно указать, чтобы попытки принудительной параметризации выполнялись в определенном классе запросов. Это можно сделать путем создания структуры плана TEMPLATE для параметризованной формы запроса и задания указания запроса PARAMETERIZATION FORCED с помощью хранимой процедуры sp_create_plan_guide. Такая разновидность структуры плана представляет собой способ включения принудительной параметризации только для определенного класса запросов, а не для всех.
Если значение параметра базы данных PARAMETERIZATION равно FORCED, можно указать, чтобы для определенного класса запросов выполнялись только попытки простой параметризации вместо принудительной. Это можно сделать путем создания структуры плана TEMPLATE для формы запроса с принудительной параметризацией и задания указания запроса PARAMETERIZATION SIMPLE с помощью хранимой процедуры sp_create_plan_guide.
Рассмотрим следующий запрос к базе данных AdventureWorks2012 :
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, может потребоваться создание нескольких структур планов для охвата всего диапазона возможных значений параметров запроса.
Следующий скрипт можно использовать как для получения параметризированного запроса, так и для дальнейшего создания по нему структуры плана:
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. |