使用计划指南可以优化查询的性能(如果不能或不想直接更改 SQL Server 2014 中实际查询的文本)。 计划指南通过向其附加查询提示或固定查询计划来影响查询优化。 当第三方供应商提供的数据库应用程序中的一小部分查询未按预期执行时,计划指南非常有用。 在计划指南中,您需要指定要优化的 Transact-SQL 语句,并选择包含所需查询提示的 OPTION 子句,或选择一个特定的查询计划用于优化该查询。 执行查询时,SQL Server 会将 Transact-SQL 语句与计划指南匹配,并在运行时将 OPTION 子句附加到查询或使用指定的查询计划。
可以创建的计划指南总数仅受可用系统资源的限制。 不过,计划指南应仅限于针对改进或稳定性能的任务关键型查询。 不应使用计划指南来影响已部署应用程序的大多数查询负载。
注释
计划指南不能在每个版本的 MicrosoftSQL Server 中使用。 有关 SQL Server 各版本支持的功能列表,请参阅 SQL Server 2014 各版本支持的功能。 计划指南在任何版本中都可见。 还可以将包含计划指南的数据库附加到任何版本。 将数据库还原或附加到升级版本的 SQL Server 时,计划指南保持不变。
计划指南的类型
可以创建以下类型的计划指南。
目标计划指南
OBJECT 计划指南与在 Transact-SQL 存储过程、标量用户定义函数、多语句表值用户定义函数和 DML 触发器上下文中执行的查询相匹配。
假设以下采用 _region 参数的@Country存储过程位于针对 AdventureWorks2012 数据库部署的数据库应用程序中:
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提示来解决此问题。 但是,由于存储过程位于已部署的应用程序中,因此无法直接修改应用程序代码。 相反,可以在 AdventureWorks2012 数据库中创建以下计划指南。
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;
若要防止在此查询上生成并行执行计划,请创建以下计划指南,并将查询提示设置为MAXDOP1参数中@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)';
重要
为sp_create_plan guide语句中的@module_or_batch和@params参数提供的值必须与实际查询中提交的相应文本匹配。 有关详细信息,请参阅 sp_create_plan_guide(Transact-SQL) 并使用 SQL Server Profiler 创建和测试计划指南。
当 PARAMETERIZATION 数据库选项设置为 FORCED 时,或者在创建 TEMPLATE 计划指南以指定一类参数化查询时,也可以针对参数化为相同形式的查询创建 SQL 计划指南。
模板计划指南
TEMPLATE 规划指南与独立查询匹配,将其参数化为指定格式。 这些计划指南用于替代数据库的当前 PARAMETERIZATION 数据库 SET 选项,以用于一类查询。
在以下任一情况下,你可以创建一个模板计划指南:
将 PARAMETERIZATION 数据库选项设置为 FORCED,但需要根据简单参数化规则编译某些查询。
PARAMETERIZATION 数据库选项设置为 SIMPLE(默认设置),但希望在查询类上尝试强制参数化。
计划指南匹配要求
计划指南的范围限定在创建它们的数据库中。 因此,只有在查询执行时数据库中当前的计划指南才能与查询匹配。 例如,如果 AdventureWorks2012 是当前数据库,则执行以下查询:
SELECT FirstName, LastName FROM Person.Person;
只有 AdventureWorks2012 数据库中的计划指南才有资格与此查询匹配。 但是,如果 AdventureWorks2012 是当前数据库,并且运行以下语句:
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 数据库 语句。
计划指南对计划缓存的影响
在模块上创建计划指南会从计划缓存中删除该模块的查询计划。 在批处理上创建 OBJECT 或 SQL 类型的计划指南会删除具有相同哈希值的批处理的查询计划。 创建 TEMPLATE 类型的计划指南会从该数据库中的计划缓存中删除所有单语句批处理。
相关任务
| 任务 | 主题 |
|---|---|
| 介绍如何创建计划指南。 | 创建新计划指南 |
| 介绍如何为参数化查询创建计划指南。 | 为参数化查询创建计划指南 |
| 介绍如何使用计划指南控制查询参数化行为。 | 使用计划指南指定查询参数化行为 |
| 介绍如何在计划指南中包含固定查询计划。 | 将固定查询计划应用于计划指南 |
| 介绍如何在计划指南中指定查询提示。 | 将查询提示附加到计划指南 |
| 介绍如何查看计划指南属性。 | 查看计划指南属性 |
| 介绍如何使用 SQL Server Profiler 创建和测试计划指南。 | 使用 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)