使用 USE PLAN 查询提示
USE PLAN 查询提示采用 xml_plan 作为参数。xml_plan 是从为查询生成的 XML 格式的查询计划派生的字符串文字。USE PLAN 查询提示可指定为独立 SQL 语句中的查询提示,也可在计划指南的 @hints 参数中进行指定。若要将查询计划附加到计划指南,建议您使用 sp_create_plan_guide 或 sp_create_plan_guide_from_handle 存储过程中的 xml_showplan 参数。
重要提示 |
---|
应始终通过指定前缀 N 来指明 xml_plan 为 Unicode 文本,例如 N'xml_plan'。这样做可确保当 SQL Server 数据库引擎解释字符串时,特定于 Unicode 标准的计划中的所有字符不会丢失。 |
在 SQL Server 中,可以通过下列方式来生成 XML 格式的查询计划:
-
重要提示 当使用 SET SHOWPLAN_XML 生成查询计划时,在将计划用于 USE PLAN 查询提示之前,必须将显示在计划中的引号 (') 通过第二个引号来转义。例如,对于包含 WHERE A.varchar = 'This is a string' 的计划,必须通过将该代码修改为 WHERE A.varchar = ''This is a string'' 来进行转义。
查询 sys.dm_exec_query_plan 动态管理函数的 query_plan 列。
SQL Server 事件探查器 Showplan XML 事件类、Showplan XML Statistics Profile 事件类和 Showplan XML For Query Compile 事件类。
有关生成和分析查询计划的详细信息,请参阅分析查询。
xml_plan 中所指定的 XML 格式的查询计划必须针对 SQL Server 安装目录中的 XSD 架构 Showplanxml.xsd 进行验证。此外,在包含 <ShowPlanXML> <BatchSequence> <Batch> <Statements> 元素的路径下,必须出现下列元素之一:
一个或多个 <StmtSimple> 元素,其中只有一个元素包含 <QueryPlan> 子元素。
一个只含有一个 <CursorPlan> 子元素的 <StmtCursor> 元素。
一个或多个不含 <QueryPlan> 子元素的 <StmtSimple> 元素,以及一个含有一个 <CursorPlan> 子元素的 <StmtCursor> 元素。
在通过使用 USE PLAN 来使用计划之前,可以更改该计划,例如更改联接顺序和运算符以及调整扫描和查找。但是,计划的格式仍然必须与 Showplanxml.xsd 相匹配。因此,您可能会无法强制执行已更改的计划。在 USE PLAN 提示中使用某个计划时,如果该计划不是 SQL Server 在优化过程中通常要考虑查询的计划之一,将发生错误。
使用 USE PLAN 查询提示生成的查询计划的缓存方式和其他查询计划的缓存方式完全一样。
USE PLAN 查询提示的限制
数据库更改(例如删除索引)可能会使 USE PLAN 所指定的查询计划无效。即使某个查询计划中没有直接引用已删除的对象,该计划也会过时。例如,查询计划中可能没有显式引用某个唯一索引,但是该索引仍然会对数据强制实施唯一性约束。USE PLAN 所引用的查询计划可以使用此约束来避免使用某些运算符强制实现特殊性。
有时,安装 SQL Server 的 Service Pack 或新版本可能会阻止您强制执行由早期版本生成的计划。因此,只要升级了服务器,就应该对所有 USE PLAN 提示进行测试。
在查询中使用 USE PLAN 提示将覆盖同一查询中使用的所有联接提示和索引提示。
USE PLAN 不能与 FORCE ORDER、EXPAND VIEWS、GROUP、UNION 或 JOIN 查询提示一起使用;当 SET FORCEPLAN 设置为 ON 时,也不能使用 USE PLAN。
通过使用 USE PLAN 只能强制执行查询优化器的典型搜索策略可以找到的查询计划。这些计划通常会指定每个联接的一个子级位于叶级。使用 USE PLAN 强制执行其他类型的查询将会导致错误。
强制实施的查询计划元素
并非 XML 格式的查询计划的所有元素都使用 USE PLAN 提示来强制实施。用于计算标量表达式的元素将被忽略,一些关系表达式也将被忽略。将强制实施查询计划的下列元素类型:
计划树结构和求值顺序。
执行算法(例如联接类型、排序和联合)。
索引操作(例如扫描、查找、交集和联合)。
显式引用的对象(例如其他表、索引和函数)。
特别地,SQL Server 将强制实施在 <RelOp> 元素下找到的 LogicalOp、PhysicalOp 和 NodeID 项,以及适用于 <PhysicalOp> 运算符的所有子元素。USE PLAN 不考虑 <RelOp> 元素下的其他内容。
重要提示 |
---|
USE PLAN 查询提示不强制实施有关 <EstimateRows> 元素所规定的基数估计的信息。由于查询优化器使用基数估计来确定用于执行查询的内存量,因此您应该维护精确的统计信息,即便在使用 USE PLAN 时也应如此。有关详细信息,请参阅使用统计信息提高查询性能。 |
下表列出了使用 USE PLAN 查询提示将强制实施的关系运算符值的 PhysicalOp 和 LogicalOp 项,以及每个 PhysicalOp 值所需的子元素。此表还包括具有与该子元素相关的 XPath 样式路径格式的每个运算符所需的其他信息。
PhysicalOp |
LogicalOp |
子元素 |
其他信息1 |
---|---|---|---|
Concatenation |
Concatenation Async Concat |
Concat |
不适用 |
Constant Scan |
Constant Scan |
ConstantScan |
不适用 |
Deleted Scan |
Deleted Scan |
DeletedScan |
Object/@Table |
UDX |
UDX |
Extension |
@UDXName |
Hash Match |
Inner Join Left Outer Join Right Outer Join Full Outer Join Left Semi Join Left Anti Semi Join Right Semi Join Right Anti Semi Join Aggregate Partial Aggregate Flow Distinct Union |
Hash |
不适用 |
RID Lookup |
RID Lookup |
IndexScan |
Object/@Database, Object/@Schema, Object/@Table |
Index Scan Clustered Index Scan |
Index Scan Clustered Index Scan |
IndexScan |
Object/@Database, Object/@Schema, Object/@Table Object/@Index |
Index Seek Clustered Index Seek |
Index Seek Clustered Index Seek |
IndexScan |
Object/@Database, Object/@Schema, Object/@Table Object/@Index |
Inserted Scan |
Inserted Scan |
InsertedScan |
Object/@Table |
Log Row Scan |
Log Row Scan |
LogRowScan |
不适用 |
Merge Join |
Inner Join Left Outer Join Right Outer Join Full Outer Join Left Semi Join Left Anti Semi Join Right Semi Join Right Anti Semi Join Cross Join Concatenation Union |
Merge |
不适用 |
Merge Interval |
Merge Interval |
MergeInterval |
不适用 |
Nested Loops |
Inner Join Left Outer Join Right Outer Join Full Outer Join Left Semi Join Left Anti Semi Join Right Semi Join Right Anti Semi Join Cross Join |
NestedLoops |
不适用 |
Parallelism |
Gather Streams Repartition Streams Distribute Streams |
Parallelism |
不适用 |
Row Count Spool |
Eager Spool Lazy Spool |
RowCountSpool2 |
不适用 |
Segment |
Segment |
Segment |
不适用 |
Sequence |
Sequence |
Sequence |
不适用 |
Sequence Project |
Compute Scalar |
SequenceProject |
不适用 |
Sort |
Sort Distinct Sort |
Sort |
不适用 |
Table Spool Index Spool |
Eager Spool Lazy Spool |
Spool2 |
@PrimaryNodeId(仅用于辅助假脱机) ../RelOp/@NodeId(仅用于表示主假脱机的 RelOp) |
Stream Aggregate |
Aggregate |
StreamAggregate |
不适用 |
Switch |
Switch |
Switch |
不适用 |
Table Scan |
Table Scan |
TableScan |
Object/@Database, Object/@Schema, Object/@Table |
Table-valued function |
Table-valued function |
TableValuedFunction |
Object/@Database, Object/@Schema, Object/@Table (名为 Object/@Table 的表值函数) |
Top |
Top |
Top |
不适用 |
Sort |
Sort |
Sort |
不适用 |
Top Sort |
TopN Sort |
TopSort |
不适用 |
Table Insert |
Insert |
Update |
Object/@Table |
1 对于每个关系运算符,这些输入的数量和顺序必须如表中所示来显示,以使用 USE PLAN 强制执行计划。
2 如果计划中包含 <RowCountSpool> 子元素(可能会作为 <RowCountSpool> 子元素或 <Spool> 子元素显示在强制执行的计划中),则强制执行该计划的能力会受到限制。同样,如果计划中包含 <Spool> 子元素(可能会作为 <Spool> 子元素或 <RowCountSpool> 子元素显示在强制执行的计划中)也是如此。
USE PLAN 将忽略 Assert、Bitmap、ComputeScalar 和 PrintDataFlow 运算符。USE PLAN 会考虑 Filter 运算符,但是不能强制该运算符在计划中的确切位置。
有关查询计划中所使用的逻辑运算符和物理运算符的详细信息,请参阅逻辑运算符和物理运算符引用。
游标支持
可以将 USE PLAN 查询提示与指定静态游标或快速只进游标(不管是通过 Transact-SQL 还是通过 API 游标函数请求的)的查询一起使用。支持带有“只进”选项的 Transact-SQL 静态游标。不支持动态游标、键集驱动游标和只进游标。
有关详细信息,请参阅对包含游标的查询使用 USE PLAN 查询提示。