在大多数情况下,将数据库升级到最新版本的 SQL Server 将导致提高查询性能。 但是,如果你有经过精心优化的性能的任务关键查询,则可能需要在升级之前保留这些查询的查询计划,方法是为每个查询创建计划指南。 如果在升级后,查询优化器为一个或多个查询选择效率较低的计划,则可以启用计划指南并强制查询优化器使用升级前计划。
若要在升级之前创建计划指南,请执行以下步骤:
使用 sp_create_plan_guide 存储过程并在 USE PLAN 查询提示中指定查询计划,记录每个任务关键查询的当前计划。
验证计划指南是否已应用于查询。
将数据库升级到较新版本的 SQL Server。
计划保存在升级后的数据库中的计划指南中,如果升级后计划出现回归,它们将作为回退措施。
建议在升级后不要启用计划指南,因为你可能错过了新版本中更好的计划或由于更新的统计信息而有益的重新编译的机会。
如果在升级后选择效率较低的计划,请激活计划指南中的所有或子集以替代新计划。
示例:
以下示例演示如何通过创建计划指南来记录查询的预升级计划。
步骤 1:收集计划
在计划指南中记录的查询计划必须采用 XML 格式。 可以通过以下方法生成 XML 格式的查询计划:
查询动态管理函数sys.dm_exec_query_plan的query_plan列。
SQL Server Profiler Showplan XML、 Showplan XML Statistics Profile 和 Showplan XML For Query Compile 事件类。
以下示例通过查询动态管理视图来收集语句 SELECT City, StateProvinceID, PostalCode FROM Person.Address ORDER BY PostalCode DESC;
的查询计划。
USE AdventureWorks;
GO
SELECT query_plan
FROM sys.dm_exec_query_stats AS qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS st
CROSS APPLY sys.dm_exec_text_query_plan(qs.plan_handle, DEFAULT, DEFAULT) AS qp
WHERE st.text LIKE N'SELECT City, StateProvinceID, PostalCode FROM Person.Address ORDER BY PostalCode DESC;%';
GO
步骤 2:创建计划指南以强制实施计划
在计划指南中使用 XML 格式的查询计划(使用先前描述的任一方法获取),将查询计划复制并粘贴为在 sp_create_plan_guide 的 OPTION 子句中指定的 USE PLAN 查询提示中的字符串。
在 XML 计划本身中,在创建计划指南之前,需要将计划中出现的引号(')用第二个引号进行转义。 例如,包含 WHERE A.varchar = 'This is a string'
的计划可以通过将代码修改为 WHERE A.varchar = ''This is a string''
来进行转义。
以下示例为步骤 1 中收集的查询计划创建一个计划指南,并将查询的 XML Showplan 插入到 @hints
参数中。 为简洁起见,示例中仅包含部分 Showplan 输出。
EXECUTE sp_create_plan_guide
@name = N'Guide1',
@stmt = N'SELECT City, StateProvinceID, PostalCode FROM Person.Address ORDER BY PostalCode DESC;',
@type = N'SQL',
@module_or_batch = NULL,
@params = NULL,
@hints = N'OPTION(USE PLAN N''<ShowPlanXML xmlns=''''https://schemas.microsoft.com/sqlserver/2004/07/showplan''''
Version=''''0.5'''' Build=''''9.00.1116''''>
<BatchSequence><Batch><Statements><StmtSimple>
...
</StmtSimple></Statements></Batch>
</BatchSequence></ShowPlanXML>'')';
GO
步骤 3:验证计划指南是否应用于查询
再次运行查询并检查生成的查询计划。 应会看到该计划与你在计划指南中指定的计划匹配。