查询提示 (Transact-SQL)

更新日期: 2007 年 9 月 15 日

指定应在整个查询中使用所指定的查询提示。查询提示影响语句中的所有运算符。如果主查询中涉及 UNION,则只有涉及 UNION 运算符的最后一个查询才能有 OPTION 子句。查询提示被指定为 OPTION 子句的一部分。如果一个或多个查询提示导致查询优化器不生成有效计划,则产生 8622 错误。

ms181714.note(zh-cn,SQL.90).gif重要提示:
由于 SQL Server 2005 查询优化器通常为查询选择最优执行计划,因此建议只将提示(包括 <query_hint>)用作经验丰富的开发人员和数据库管理员的最终手段。

适用范围:

DELETE

INSERT

SELECT

UPDATE

主题链接图标Transact-SQL 语法约定

语法

<query_hint > ::= 
{ { HASH | ORDER } GROUP 
  | { CONCAT | HASH | MERGE } UNION 
  | { LOOP | MERGE | HASH } JOIN 
  | FAST number_rows 
  | FORCE ORDER 
  | MAXDOP number_of_processors 
  | OPTIMIZE FOR ( @variable_name = literal_constant [ , ...n ] ) 
  | PARAMETERIZATION { SIMPLE | FORCED }
  | RECOMPILE
  | ROBUST PLAN 
  | KEEP PLAN 
  | KEEPFIXED PLAN
  | EXPAND VIEWS 
  | MAXRECURSION number 
  | USE PLAN N'xml_plan'
} 

参数

  • { HASH | ORDER } GROUP
    指定在查询的 GROUP BY、DISTINCT 或 COMPUTE 子句中所说明的聚合应使用哈希或排列。
  • { MERGE |HASH |CONCAT } UNION
    指定所有 UNION 运算由合并、哈希或串联 UNION 集执行。如果指定了多个 UNION 提示,查询优化器就会从这些指定的提示中选择开销最少的策略。

    ms181714.note(zh-cn,SQL.90).gif注意:
    如果在 FROM 子句中亦为任何特定联接表对指定了 <joint_hint>,则该提示优先于 OPTION 子句中指定的任何 <join_hint>。
  • { LOOP | MERGE | HASH } JOIN
    指定整个查询中的所有联接操作由 LOOP JOIN、MERGE JOIN 或 HASH JOIN 执行。如果指定了多个联接提示,则优化器从允许的联接策略中选择开销最少的联接策略。

    如果在同一个查询中还为一对特定的表指定了联接提示,则虽然仍须遵守查询提示,但该联接提示将优先联接这两个表。因此,为这对表指定的联接提示可能只限制选择查询提示中允许的联接方法。有关详细信息,请参阅提示 (Transact-SQL)

  • FAST number_rows
    指定对查询进行优化,以便快速检索第一个 number_rows.。该值是非负整数。在返回第一个 number_rows 后,查询继续执行并生成完整的结果集。
  • FORCE ORDER
    指定在查询优化过程中保持由查询语法指示的联接顺序。

    ms181714.note(zh-cn,SQL.90).gif注意:
    使用 FORCE ORDER 不会影响查询优化器可能的角色逆转行为。有关详细信息,请参阅了解哈希联接

    有关在查询包含视图时 SQL Server 查询优化器如何强制使用 FORCE ORDER 提示的信息,请参阅视图解析

  • MAXDOP number
    对指定了 sp_configuremax degree of parallelism 配置选项的查询覆盖该选项。MAXDOP 查询提示可以超出用 sp_configure 配置的值。当使用 MAXDOP 查询提示时,所有和 max degree of parallelism 配置选项一起使用的语义规则均适用。有关详细信息,请参阅max degree of parallelism 选项
  • @variable_name
    在查询中使用的本地变量的名称,可以为其分配用于 OPTIMIZE FOR 查询提示的值。
  • literal_constant
    要分配给 @variable_name 并用于 OPTIMIZE FOR 查询提示的文字常量值。literal_constant 只在查询优化期间使用,在查询执行期间不作为 @variable_name 的值使用。literal_constant 可以是任意可用文字常量表示的 SQL Server 系统数据类型。literal_constant 的数据类型必须可隐式转换为查询中 @variable_name 所引用的数据类型。
  • ,…n
    指示可以为多个 @variable_name 分配用于 OPTIMIZE FOR 查询提示的 literal_constant
  • PARAMETERIZATION { SIMPLE | FORCED }
    指定在编译查询时 SQL Server 查询优化器应用于此查询的参数化规则。

    ms181714.note(zh-cn,SQL.90).gif重要提示:
    PARAMETERIZATION 查询提示只能在计划指南中指定。不能直接在查询中指定该查询提示。

    SIMPLE 指示查询优化器尝试进行简单参数化。FORCED 指示优化器尝试进行强制参数化。PARAMETERIZATION 查询提示用于覆盖计划指南中 PARAMETERIZATION 数据库 SET 选项的当前设置。有关详细信息,请参阅使用计划指南指定查询参数化行为

  • RECOMPILE
    指示 SQL Server 2005 数据库引擎在执行为查询生成的计划后将其丢弃,从而在下次执行同一查询时强制查询优化器重新编译查询计划。如果未指定 RECOMPILE,数据库引擎将缓存查询计划并重新使用它们。在编译查询计划时,RECOMPILE 查询提示将使用查询中任意本地变量的当前值,如果查询位于存储过程中,这些当前值将传递给任意参数。

    在只须重新编译存储过程中的一部分查询,而不是重新编译整个存储过程时,RECOMPILE 是创建使用 WITH RECOMPILE 子句的存储过程的很有用的替代方法。有关详细信息,请参阅重新编译存储过程。在创建计划指南时,RECOMPILE 也很有用。有关详细信息,请参阅使用计划指南在部署的应用程序中优化查询

  • ROBUST PLAN
    强制查询优化器尝试一个计划,该计划可能以性能为代价获得最大可能的行大小。处理查询时,中间表和运算符可能需要存储和处理比输入行宽的行。在有些情况下,行可能很宽,以致某个运算符无法处理行。如果发生这种情况,数据库引擎将在查询执行过程中生成错误。通过使用 ROBUST PLAN,可以指示查询优化器不考虑可能会遇到该问题的所有查询计划。

    如果不能使用这样的计划,查询优化器将返回错误而不是延迟对查询执行的错误检测。行可以包含可变长度列;数据库引擎允许将行大小定义为超过数据库引擎处理能力的最大可能的大小。通常,应用程序存储实际大小在数据库引擎处理能力范围内的行,而不管最大可能大小。如果数据库引擎遇到过长的行,则返回执行错误。

  • KEEP PLAN
    强制查询优化器对查询放宽估计的重新编译阈值。当对表的索引列更改(通过运行 UPDATE、DELETE 或 INSERT 语句)达到估计数目时自动重新编译查询,该估计数目即为估计的重新编译阈值。指定 KEEP PLAN 可确保当表有多个更新时不会频繁地对查询进行重新编译。
  • KEEPFIXED PLAN
    强制查询优化器不因统计信息的更改而重新编译查询。指定 KEEPFIXED PLAN 可确保仅当更改基础表的架构或在那些表上执行 sp_recompile 时才重新编译查询。
  • EXPAND VIEWS
    指定展开索引视图,而且查询优化器不将任何索引视图看作是查询中任何部分的替代。当视图名称由查询文本中的视图定义替换时,视图将展开。

    实际上,该查询提示不允许在查询计划中直接使用索引视图和直接在索引视图上使用索引。

    只有在查询的 SELECT 部分中直接引用视图,而且指定 WITH (NOEXPAND) 或 WITH (NOEXPAND, INDEX( index_val [ ,...n ] ) ) 时,才不展开索引视图。有关查询提示 WITH (NOEXPAND) 的详细信息,请参阅 FROM (Transact-SQL)

    只有语句的 SELECT 部分的视图(包括 INSERT、UPDATE 和 DELETE 语句中的视图)才受提示影响。

  • MAXRECURSION number
    指定该查询允许的最大递归数。number 是介于 0 至 32767 之间的非负整数。如果指定 0,则没有限制。如果未指定此选项,则对服务器的默认限制为 100。

    当在查询执行期间达到指定或默认的 MAXRECURSION 数量限制时,将结束查询并返回错误。

    由于此错误,该语句的所有结果都被回滚。如果该语句为 SELECT 语句,则可能会返回部分结果或不返回结果。所返回的任何部分结果都可能无法包括超过指定最大递归级别的递归级别上的所有行。

    有关详细信息,请参阅 WITH common_table_expression (Transact-SQL)

  • USE PLAN N**'xml_plan'**
    强制查询优化器对查询使用由 'xml_plan' 指定的现有查询计划。有关详细信息,请参阅使用计划强制来指定查询计划。不能使用 INSERT、UPDATE 或 DELETE 语句指定 USE PLAN。

备注

只有在 INSERT 语句中使用了 SELECT 子句时,才能在该语句中指定查询提示。

只能在顶级查询中指定查询提示,不能在子查询指定。

示例

A. 使用 MERGE JOIN

下面的示例指定查询中的 JOIN 操作由 MERGE JOIN 执行。

USE AdventureWorks;
GO
SELECT * 
FROM Sales.Customer AS c
INNER JOIN Sales.CustomerAddress AS ca
ON c.CustomerID = ca.CustomerID
WHERE TerritoryID = 5
OPTION (MERGE JOIN);
GO

B. 使用 OPTIMIZE FOR

下面的示例指示在优化查询时查询优化器对本地变量 @city_name 使用 'Seattle' 值。

DECLARE @city_name nvarchar(30)
SET @city_name = 'Ascheim'
SELECT * FROM Person.Address
WHERE City = @city_name
OPTION ( OPTIMIZE FOR (@city_name = 'Seattle') );
GO

C. 使用 MAXRECURSION

可以使用 MAXRECURSION 来防止不合理的递归公用表表达式进入无限循环。以下示例特意创建了一个无限循环,然后使用 MAXRECURSION 提示将递归级别限制为两级。

USE AdventureWorks;
GO
--Creates an infinite loop
WITH cte (EmployeeID, ManagerID, Title) as
(
    SELECT EmployeeID, ManagerID, Title
    FROM HumanResources.Employee
    WHERE ManagerID IS NOT NULL
  UNION ALL
    SELECT cte.EmployeeID, cte.ManagerID, cte.Title
    FROM cte 
    JOIN  HumanResources.Employee AS e 
        ON cte.ManagerID = e.EmployeeID
)
--Uses MAXRECURSION to limit the recursive levels to 2
SELECT EmployeeID, ManagerID, Title
FROM cte
OPTION (MAXRECURSION 2);
GO

更正代码错误之后就不再需要 MAXRECURSION

D. 使用 UNION

以下示例使用 MERGE UNION 查询提示。

USE AdventureWorks ;
GO
SELECT *
FROM HumanResources.Employee e1
UNION
SELECT *
FROM HumanResources.Employee e2
OPTION (MERGE UNION) ;
GO

E. 使用 HASH GROUP 和 FAST

以下示例使用 HASH GROUPFAST 查询提示。

USE AdventureWorks ;
GO
SELECT ProductID, OrderQty, SUM(LineTotal) AS Total
FROM Sales.SalesOrderDetail
WHERE UnitPrice < $5.00
GROUP BY ProductID, OrderQty
ORDER BY ProductID, OrderQty
OPTION (HASH GROUP, FAST 10) ;
GO

F. 使用 MAXDOP

以下示例使用 MAXDOP 查询提示。

USE AdventureWorks ;
GO
SELECT ProductID, OrderQty, SUM(LineTotal) AS Total
FROM Sales.SalesOrderDetail
WHERE UnitPrice < $5.00
GROUP BY ProductID, OrderQty
ORDER BY ProductID, OrderQty
OPTION (MAXDOP 2);
GO

请参阅

参考

提示 (Transact-SQL)

帮助和信息

获取 SQL Server 2005 帮助

更改历史记录

版本 历史记录

2007 年 9 月 15 日

更改的内容:
  • 如果 MAXDOP 查询提示超过了使用 sp_configure 配置的值,则该查询提示不起作用。

2006 年 7 月 17 日

新增内容:
  • 添加了示例 C 至 F。