为参数化查询创建计划指南

TEMPLATE 规划指南与独立查询匹配,将其参数化为指定格式。

以下示例创建一个计划指南,该指南与参数化到指定窗体的任何查询匹配,并指示 SQL Server 强制参数化查询。 以下两个查询在语法上是等效的,但只与其常量文本值不同。

SELECT * FROM AdventureWorks2012.Sales.SalesOrderHeader AS h  
INNER JOIN AdventureWorks2012.Sales.SalesOrderDetail AS d   
    ON h.SalesOrderID = d.SalesOrderID  
WHERE h.SalesOrderID = 45639;  
  
SELECT * FROM AdventureWorks2012.Sales.SalesOrderHeader AS h  
INNER JOIN AdventureWorks2012.Sales.SalesOrderDetail AS d   
    ON h.SalesOrderID = d.SalesOrderID  
WHERE h.SalesOrderID = 45640;  

下面是有关查询参数化形式的计划指南:

EXEC sp_create_plan_guide   
    @name = N'TemplateGuide1',  
    @stmt = N'SELECT * FROM AdventureWorks2012.Sales.SalesOrderHeader AS h  
              INNER JOIN AdventureWorks2012.Sales.SalesOrderDetail AS d   
                  ON h.SalesOrderID = d.SalesOrderID  
              WHERE h.SalesOrderID = @0',  
    @type = N'TEMPLATE',  
    @module_or_batch = NULL,  
    @params = N'@0 int',  
    @hints = N'OPTION(PARAMETERIZATION FORCED)';  

在前面的示例中,参数的值 @stmt 是查询的参数化形式。 获取此值以用于sp_create_plan_guide的唯一可靠方法是使用 sp_get_query_template 系统存储过程。 以下脚本可用于获取参数化查询,然后为其创建计划指南。

DECLARE @stmt nvarchar(max);  
DECLARE @params nvarchar(max);  
EXEC sp_get_query_template   
    N'SELECT * FROM AdventureWorks2012.Sales.SalesOrderHeader AS h  
      INNER JOIN AdventureWorks2012.Sales.SalesOrderDetail AS d   
          ON h.SalesOrderID = d.SalesOrderID  
      WHERE h.SalesOrderID = 45639;',  
    @stmt OUTPUT,   
    @params OUTPUT  
EXEC sp_create_plan_guide N'TemplateGuide1',   
    @stmt,   
    N'TEMPLATE',   
    NULL,   
    @params,   
    N'OPTION(PARAMETERIZATION FORCED)';  

重要

传递给sp_get_query_template的参数中的@stmt常量文本的值可能会影响为替换文本的参数选择的数据类型。 这会影响计划指导匹配。 可能需要创建多个计划指南来处理不同的参数值范围。

还可以将 TEMPLATE 计划指南与 SQL 计划指南一起使用。 例如,可以创建 TEMPLATE 计划指南,以确保参数化查询类。 然后,可以针对该查询的参数化形式创建 SQL 计划指南。