查询提示 (Transact-SQL)

适用于:Microsoft Fabric Microsoft Fabric SQL 数据库中Microsoft Fabric Warehouse 中的 SQL Server Azure SQL 数据库 Azure SQL 托管实例SQL 分析终结点

查询提示指定在查询范围内使用指示的提示。 它们会影响语句中的所有运算符。 如果 UNION 主查询涉及,则只有涉及作的最后一个 UNION 查询才能有子 OPTION 句。 查询提示指定为 OPTION 子句的一部分。 如果一个或多个查询提示导致查询优化器无法生成有效的计划,则会发生错误 8622。

谨慎

由于 SQL Server 查询优化器通常为查询选择最佳执行计划,因此我们建议仅使用提示作为经验丰富的开发人员和数据库管理员的最后手段。

适用于:

Transact-SQL 语法约定

语法

<query_hint> ::=
{ { HASH | ORDER } GROUP
  | { CONCAT | HASH | MERGE } UNION
  | { LOOP | MERGE | HASH } JOIN
  | DISABLE_OPTIMIZED_PLAN_FORCING
  | EXPAND VIEWS
  | FAST <integer_value>
  | FORCE ORDER
  | { FORCE | DISABLE } EXTERNALPUSHDOWN
  | { FORCE | DISABLE } SCALEOUTEXECUTION
  | IGNORE_NONCLUSTERED_COLUMNSTORE_INDEX
  | KEEP PLAN
  | KEEPFIXED PLAN
  | MAX_GRANT_PERCENT = <numeric_value>
  | MIN_GRANT_PERCENT = <numeric_value>
  | MAXDOP <integer_value>
  | MAXRECURSION <integer_value>
  | NO_PERFORMANCE_SPOOL
  | OPTIMIZE FOR ( @variable_name { UNKNOWN | = <literal_constant> } [ , ...n ] )
  | OPTIMIZE FOR UNKNOWN
  | PARAMETERIZATION { SIMPLE | FORCED }
  | QUERYTRACEON <integer_value>
  | RECOMPILE
  | ROBUST PLAN
  | USE HINT ( 'hint_name' [ , ...n ] )
  | USE PLAN N'<xml_plan>'
  | TABLE HINT ( <exposed_object_name> [ , <table_hint> [ [ , ] ...n ] ] )
  | FOR TIMESTAMP AS OF '<point_in_time>'
}

<table_hint> ::=
{ NOEXPAND [ , INDEX ( <index_value> [ , ...n ] ) | INDEX = ( <index_value> ) ]
  | INDEX ( <index_value> [ , ...n ] ) | INDEX = ( <index_value> )
  | FORCESEEK [ ( <index_value> ( <index_column_name> [ , ... ] ) ) ]
  | FORCESCAN
  | HOLDLOCK
  | NOLOCK
  | NOWAIT
  | PAGLOCK
  | READCOMMITTED
  | READCOMMITTEDLOCK
  | READPAST
  | READUNCOMMITTED
  | REPEATABLEREAD
  | ROWLOCK
  | SERIALIZABLE
  | SNAPSHOT
  | SPATIAL_WINDOW_MAX_CELLS = <integer_value>
  | TABLOCK
  | TABLOCKX
  | UPDLOCK
  | XLOCK
}

论据

{ HASH |ORDER } GROUP

指定查询或GROUP BY子句描述的DISTINCT聚合应使用哈希或排序。

  • 通常,基于哈希的算法可以提高涉及大型或复杂分组集的查询的性能。
  • 通常,基于排序的算法可以提高涉及小型或简单分组集的查询的性能。

{ MERGE |HASH |CONCAT } UNION

指定所有 UNION 作都通过合并、哈希或串联 UNION 集运行。 如果指定了多个 UNION 提示,查询优化器将从指定的提示中选择成本最低的策略。

  • 通常,基于合并的算法作可以提高涉及已排序输入的查询的性能。
  • 通常,基于哈希的算法可以提高涉及未排序或大型输入的查询的性能。
  • 通常,基于串联的算法可以提高涉及不同或小型输入的查询的性能。

{ LOOP |MERGE |HASH } JOIN

指定所有联接作由LOOP JOIN整个MERGE JOINHASH JOIN查询或整个查询执行。 如果指定多个联接提示,优化器将从允许的联接中选择成本最低的联接策略。

如果在特定表对的同一查询子 FROM 句中指定联接提示,则此联接提示优先于两个表的联接。 不过,仍必须遵循查询提示。 表对的联接提示只能限制在查询提示中选择允许的联接方法。 有关详细信息,请参阅 联接提示

DISABLE_OPTIMIZED_PLAN_FORCING

适用于:SQL Server(SQL Server 2022 (16.x) 及更高版本)

禁用查询的 优化计划强制

优化计划强制执行减少了重复强制查询的编译开销。 生成查询执行计划后,将会存储特定编译步骤以作为优化重播脚本重复使用。 在查询存储中,优化重播脚本作为压缩的显示计划 XML 的一部分存储在隐藏属性 OptimizationReplay 中。

展开视图

指定已展开的索引视图。 此外,指定查询优化器不将任何索引视图视为任何查询部件的替代项。 当视图定义替换查询文本中的视图名称时,视图将展开。

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

注释

如果查询部分有对视图的 SELECT 直接引用,则索引视图将保持精简。 如果指定或WITH (NOEXPAND)指定WITH (NOEXPAND, INDEX( <index_value> [ , *...n* ] ) ),视图也会保持精简状态。 有关查询提示 NOEXPAND的详细信息,请参阅 使用 NOEXPAND

该提示仅影响语句SELECT部分中的视图,包括这些视图,INSERTUPDATEMERGE以及DELETE语句。

FAST integer_value

指定查询经过优化,以便快速检索第一 个integer_value 行数。 此结果是非负整数。 返回第一 个integer_value 行数后,查询将继续执行并生成其完整结果集。

FORCE ORDER

指定在查询优化期间保留查询语法指示的联接顺序。 使用 FORCE ORDER 不会影响查询优化器可能的角色逆转行为。

FORCE ORDER 保留查询中指定的联接顺序,这可能会提高涉及复杂联接条件或提示的查询的性能或一致性。

注释

MERGE在语句中,除非指定了子句,WHEN SOURCE NOT MATCHED否则在目标表作为默认联接顺序之前访问源表。 指定 FORCE ORDER 保留此默认行为。

{ FORCE |DISABLE } EXTERNALPUSHDOWN

强制或禁用 Hadoop 中限定表达式计算的下推。 仅适用于使用 PolyBase 的查询。 不会向下推送到 Azure 存储。

{ FORCE |DISABLE } SCALEOUTEXECUTION

强制或禁用在 SQL Server 2019 大数据群集中使用外部表的 PolyBase 查询的横向扩展执行。 仅使用 SQL 大数据群集的主实例的查询才遵循此提示。 横向扩展发生在大数据群集的计算池中。

KEEP PLAN

更改临时表的 重新编译阈值 ,使其与永久表的阈值相同。 如果对表进行了估计的索引列更改,则估计的重新编译阈值会启动查询的自动重新编译,方法是运行以下语句之一:

  • UPDATE
  • DELETE
  • MERGE
  • INSERT

指定 KEEP PLAN 可确保查询在对表进行多次更新时不经常重新编译。

KEEPFIXED 计划

由于统计信息更改,强制查询优化器不重新编译查询。 指定 KEEPFIXED PLAN 可确保仅当基础表的架构发生更改或 sp_recompile 针对这些表运行时,查询才会重新编译。

IGNORE_NONCLUSTERED_COLUMNSTORE_INDEX

适用于:SQL Server(从 SQL Server 2012 (11.x)开始)。

阻止查询使用非聚集内存优化列存储索引。 如果查询包含查询提示以避免使用列存储索引,而索引提示则使用列存储索引,则提示冲突并且查询返回错误。

MAX_GRANT_PERCENT = <numeric_value>

适用于:SQL Server(从 SQL Server 2012 (11.x) Service Pack 3、SQL Server 2014 (12.x) Service Pack 2 和 Azure SQL 数据库开始。

配置内存限制的最大 PERCENT 内存授予大小。 如果查询在用户定义的资源池中运行,则保证查询不会超过此限制。 在这种情况下,如果查询没有所需的最小内存,则系统会引发错误。 如果查询在系统池(默认值)中运行,则它至少获取运行所需的内存。 如果资源调控器设置低于此提示指定的值,则实际限制可能会降低。 有效值介于 0.0 和 100.0 之间。

内存授予提示不适用于索引创建或索引重新生成。

MIN_GRANT_PERCENT = <numeric_value>

适用于:SQL Server(从 SQL Server 2012 (11.x) Service Pack 3、SQL Server 2014 (12.x) Service Pack 2 和 Azure SQL 数据库开始。

配置的内存限制中的 PERCENT 最小内存授予大小。 保证查询获得 MAX(required memory, min grant) ,因为至少需要内存才能启动查询。 有效值介于 0.0 和 100.0 之间。

无论大小如何,min_grant_percent内存授予选项都会 sp_configure 覆盖选项(每个查询(KB)的最小内存。 内存授予提示不适用于索引创建或索引重新生成。

MAXDOP <integer_value>

适用于:SQL Server(从 SQL Server 2008(10.0.x)开始)和 Azure SQL 数据库。

重写 最大并行度 配置选项 sp_configure。 此外,替代指定此选项的查询的资源调控器。 查询 MAXDOP 提示可以超出配置 sp_configure的值。 如果MAXDOP超出使用资源调控器配置的值,数据库引擎将使用 MAXDOP 中所述的资源调控器值。 使用查询提示时,与MAXDOP配置选项一起使用的所有语义规则都适用。 有关详细信息,请参阅 服务器配置:最大并行度

警告

如果 MAXDOP 设置为零,则服务器选择最大并行度。

MAXRECURSION <integer_value>

指定此查询允许的最大递归数。 number 是介于 0 和 32,767 之间的正整数。 指定 0 时,不会应用任何限制。 如果未指定此选项,则服务器的默认限制为 100。

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

由于此错误,语句的所有效果都会回滚。 如果语句是 SELECT 语句,则可能会返回部分结果或未返回任何结果。 返回的任何部分结果可能不包括超出指定最大递归级别的递归级别的所有行。

有关详细信息,请参阅 WITH common_table_expression

NO_PERFORMANCE_SPOOL

适用于:SQL Server(从 SQL Server 2016(13.x)开始)和 Azure SQL 数据库。

防止将后台处理程序运算符添加到查询计划(在需要后台处理程序以确保有效的更新语义时的计划除外)。 在某些情况下,后台处理程序作员可以降低性能。 例如,如果有许多并发查询与后台处理程序作一起运行,则后台处理程序使用 tempdb,并且 tempdb 可能会发生争用。

OPTIMIZE FOR ( @variable_name { UNKNOWN | = <literal_constant> } [ , ...n ]

指示查询优化器在编译和优化查询时对局部变量使用特定值。 仅在查询优化期间使用该值,在查询执行期间不使用该值。

  • @variable_name

    查询中使用的局部变量的名称,可以将值分配给该变量以用于 OPTIMIZE FOR 查询提示。

  • UNKNOWN

    指定查询优化器使用统计数据而不是初始值来确定查询优化过程中局部变量的值。

  • literal_constant

    要分配@variable_nameOPTIMIZE FOR用于查询提示的文本常量值。 literal_constant 仅在查询优化期间使用,而不是在查询执行期间 用作@variable_name 的值。 literal_constant 可以是任何可以表示为文本常量的 SQL Server 系统数据类型。 literal_constant的数据类型必须隐式转换为查询中@variable_name引用的数据类型。

OPTIMIZE FOR 可以抵消优化器的默认参数检测行为。 也可以在创建计划指南时使用 OPTIMIZE FOR 。 有关详细信息,请参阅重新编译存储过程

OPTIMIZE FOR UNKNOWN

指示查询优化器在所有列值中使用谓词的平均选择性,而不是在编译和优化查询时使用运行时参数值。

如果使用 OPTIMIZE FOR @variable_name = <literal_constant>OPTIMIZE FOR UNKNOWN 在同一查询提示中,查询优化器将使用为特定值指定的 literal_constant 。 查询优化器对变量值的其余部分使用 UNKNOWN。 这些值仅在查询优化期间使用,而不是在查询执行期间使用。

PARAMETERIZATION { SIMPLE |FORCED }

指定 SQL Server 查询优化器在编译时应用于查询的参数化规则。

重要

PARAMETERIZATION查询提示只能在计划指南中指定,以替代数据库PARAMETERIZATION选项的SET当前设置。 不能直接在查询中指定它。

有关详细信息,请参阅 使用计划指南指定查询参数化行为

SIMPLE 指示查询优化器尝试简单的参数化。 FORCED 指示查询优化器尝试强制参数化。 有关详细信息,请参阅 查询处理体系结构指南中的强制参数化,以及 查询处理体系结构指南中的简单参数化

QUERYTRACEON <integer_value>

此选项允许仅在单查询编译期间启用影响计划的跟踪标志。 与其他查询级别选项一样,可以将它与计划指南一起使用,以匹配从任何会话执行的查询的文本,并在编译此查询时自动应用影响计划的跟踪标志。 仅查询优化器跟踪标志支持此选项 QUERYTRACEON 。 有关详细信息,请参阅 跟踪标志

如果使用不受支持的跟踪标志号,则使用此选项不会返回任何错误或警告。 如果指定的跟踪标志不是影响查询执行计划的标志,则以无提示方式忽略该选项。

若要在查询中使用多个跟踪标志,请为每个不同的跟踪标志编号指定一个 QUERYTRACEON 提示。

重新 编译

指示 SQL Server 数据库引擎为查询生成新的临时计划,并在查询完成执行后立即放弃该计划。 当同一查询在没有提示的情况下运行 RECOMPILE 时,生成的查询计划不会替换存储在缓存中的计划。 如果不指定 RECOMPILE,数据库引擎将缓存查询计划并重复使用它们。 编译查询计划时, RECOMPILE 查询提示使用查询中任何局部变量的当前值。 如果查询位于存储过程内,则传递给任何参数的当前值。

RECOMPILE 是创建存储过程的有用替代方法。 RECOMPILE WITH RECOMPILE仅当存储过程内的查询子集(而不是整个存储过程)必须重新编译时,使用子句。 有关详细信息,请参阅重新编译存储过程RECOMPILE 创建计划指南时也很有用。

可靠计划

强制查询优化器尝试用于最大潜在行大小的计划,可能以牺牲性能为代价。 处理查询时,中间表和运算符可能需要存储和处理比处理查询时任何一个输入行宽的行。 行可能非常宽,有时,特定运算符无法处理该行。 如果行宽,数据库引擎在查询执行过程中会生成错误。 通过使用 ROBUST PLAN,指示查询优化器不要考虑可能遇到此问题的任何查询计划。

如果无法实现此类计划,查询优化器将返回错误,而不是将错误检测推迟到查询执行。 行可以包含可变长度列;数据库引擎允许定义具有超出数据库引擎处理这些行的最大潜在大小。 通常,尽管存在最大的潜在大小,但应用程序会存储数据库引擎可以处理的限制内具有实际大小的行。 如果数据库引擎遇到过长行,则会返回执行错误。

USE HINT (“hint_name” )

适用于:SQL Server(从 SQL Server 2016 (13.x) SP1 开始)、Azure SQL 数据库和 Azure SQL 托管实例。

向查询处理器提供一个或多个额外提示。 使用 单引号内的提示名称指定额外的提示。

小窍门

提示名称不区分大小写。

支持以下提示名称:

提示 DESCRIPTION
'ABORT_QUERY_EXECUTION' 阻止查询执行。 旨在用作 查询存储提示 ,让管理员阻止将来执行已知有问题的查询,例如影响应用程序工作负荷的非必要查询。 有关详细信息,请参阅 阻止将来执行有问题的查询

适用于:Azure SQL 数据库和 SQL Server 2025 (17.x) 预览版。 此提示 处于预览状态
'ASSUME_FIXED_MIN_SELECTIVITY_FOR_REGEXP' REGEXP_LIKE基数估计模型提供默认的选择性值。 如果默认估计过高,请使用此提示。 它将选择性设置为固定较低的选择性值。

适用于: SQL Server 2025 (17.x) 预览版及更高版本以及 Azure SQL 数据库
'ASSUME_FIXED_MAX_SELECTIVITY_FOR_REGEXP' REGEXP_LIKE基数估计模型提供默认的选择性值。 如果默认估计太低,请使用此提示。 它将选择性设置为固定更高的选择性值。

适用于: SQL Server 2025 (17.x) 预览版及更高版本以及 Azure SQL 数据库
'ASSUME_JOIN_PREDICATE_DEPENDS_ON_FILTERS' 在 SQL Server 2014(12.x)和更高版本的查询优化器 基数估计 模型下,使用简单包含假设而不是联接的默认基本包含假设生成查询计划。 此提示名称等效于 跟踪标志 9476。
'ASSUME_MIN_SELECTIVITY_FOR_FILTER_ESTIMATES' 在估算筛选器的 AND 谓词以考虑完全关联时,使用最小选择性生成计划。 当与 SQL Server 2012 (11.x) 和早期版本的基数估计模型一起使用时,此提示名称等效于 跟踪标志 4137,当 跟踪标志 9471 与 SQL Server 2014(12.x)及更高版本的基数估计模型一起使用时,其效果类似。
'ASSUME_FULL_INDEPENDENCE_FOR_FILTER_ESTIMATES' 在估算筛选器的 AND 谓词以考虑完全独立时,使用最大选择性生成计划。 此提示名称是 SQL Server 2012 (11.x) 和早期版本的基数估计模型的默认行为,等效于在 SQL Server 2014 (12.x) 及更高版本中用于基数估计模型时跟踪 标志 9472。

适用于: Azure SQL 数据库
'ASSUME_PARTIAL_CORRELATION_FOR_FILTER_ESTIMATES' 在估算筛选器的 AND 谓词以考虑部分相关性时,生成使用最多到最少选择性的计划。 此提示名称是 SQL Server 2014 (12.x) 及更高版本基数估计模型的默认行为。

适用于: Azure SQL 数据库
'DISABLE_BATCH_MODE_ADAPTIVE_JOINS' 禁用批处理模式自适应联接。 有关详细信息,请参阅 Batch 模式自适应联接

适用于:SQL Server 2017 (14.x) 及更高版本和 Azure SQL 数据库
'DISABLE_BATCH_MODE_MEMORY_GRANT_FEEDBACK' 禁用批处理模式内存授予反馈。 有关详细信息,请参阅 Batch 模式内存授予反馈

适用于:SQL Server 2017 (14.x) 及更高版本和 Azure SQL 数据库
'DISABLE_DEFERRED_COMPILATION_TV' 禁用表变量延迟编译。 有关详细信息,请参阅表变量延迟编译

适用于:SQL Server 2019 (15.x) 及更高版本和 Azure SQL 数据库
'DISABLE_INTERLEAVED_EXECUTION_TVF' 禁用多语句表值函数的交错执行。 有关详细信息,请参阅 多语句表值函数的交错执行

适用于:SQL Server 2017 (14.x) 及更高版本和 Azure SQL 数据库
'DISABLE_OPTIMIZED_HALLOWEEN_PROTECTION' 禁用优化的万圣节保护。 有关详细信息,请参阅 优化万圣节保护

适用于:SQL Server 2025 (17.x) 预览版
'DISABLE_OPTIMIZED_NESTED_LOOP' 指示查询处理器在生成查询计划时不要对优化的嵌套循环联接使用排序作(批处理排序)。 此提示名称等效于 跟踪标志 2340。 此提示也适用于显式排序和批处理排序。
'DISABLE_OPTIMIZER_ROWGOAL' 导致 SQL Server 生成计划,该计划不会对包含以下关键字的查询使用行目标修改:

- TOP
- OPTION (FAST N)
- IN
- EXISTS

此提示名称等效于 跟踪标志 4138。
'DISABLE_PARAMETER_SNIFFING' 指示查询优化器使用平均数据分布,同时使用一个或多个参数编译查询。 此指令使查询计划独立于编译查询时首次使用的参数值。 此提示名称等效于 跟踪标志 4136 或 数据库范围的配置 设置 PARAMETER_SNIFFING = OFF
'DISABLE_ROW_MODE_MEMORY_GRANT_FEEDBACK' 禁用行模式内存授予反馈。 有关详细信息,请参阅 行模式内存授予反馈

适用于:SQL Server 2019 (15.x) 及更高版本和 Azure SQL 数据库
'DISABLE_TSQL_SCALAR_UDF_INLINING' 禁用标量 UDF 内联。 有关详细信息,请参阅 标量 UDF 内联

适用于:SQL Server 2019 (15.x) 及更高版本和 Azure SQL 数据库
'DISALLOW_BATCH_MODE' 禁用批处理模式执行。 有关详细信息,请参阅 执行模式

适用于:SQL Server 2019 (15.x) 及更高版本和 Azure SQL 数据库
'ENABLE_HIST_AMENDMENT_FOR_ASC_KEYS' 为需要基数估计的任何前导索引列启用自动生成的快速统计信息(直方图修正)。 用于估计基数的直方图在查询编译时进行调整,以考虑此列的实际最大值或最小值。 此提示名称等效于 跟踪标志 4139。
'ENABLE_OPTIMIZED_HALLOWEEN_PROTECTION' 启用优化的万圣节保护。 有关详细信息,请参阅 优化万圣节保护

适用于:SQL Server 2025 (17.x) 预览版
'ENABLE_QUERY_OPTIMIZER_HOTFIXES' 启用查询优化器修补程序(SQL Server 累积更新和 Service Pack 中发布的更改)。 此提示名称等效于 跟踪标志 4199 或 数据库范围的配置 设置 QUERY_OPTIMIZER_HOTFIXES = ON
'FORCE_DEFAULT_CARDINALITY_ESTIMATION' 强制查询优化器使用与当前数据库兼容性级别相对应的 基数估计 模型。 使用此提示替代 数据库范围的配置 设置 LEGACY_CARDINALITY_ESTIMATION = ON跟踪标志 9481。
'FORCE_LEGACY_CARDINALITY_ESTIMATION' 强制查询优化器使用 SQL Server 2012 (11.x) 和早期版本的 基数估计 模型。 此提示名称等效于 跟踪标志 9481 或 数据库范围的配置 设置 LEGACY_CARDINALITY_ESTIMATION = ON
'QUERY_OPTIMIZER_COMPATIBILITY_LEVEL_n' 1 在查询级别强制执行查询优化器行为。 发生此行为,就像使用数据库兼容性级别 n 编译查询一样,其中 n 是受支持的数据库兼容性级别。 有关当前支持的 n 值的列表,请参阅 sys.dm_exec_valid_use_hints

适用于:SQL Server 2017 (14.x) CU 10 及更高版本以及 Azure SQL 数据库
'QUERY_PLAN_PROFILE' 2 为查询启用轻型分析。 当包含此新提示的查询完成时,将触发新的扩展事件 query_plan_profile。 此扩展事件公开执行统计信息和实际执行计划 XML,类似于 query_post_execution_showplan 扩展事件,但仅适用于包含新提示的查询。

适用于:SQL Server 2016 (13.x) SP 2 CU 3、SQL Server 2017 (14.x) CU 11 及更高版本

1 如果通过数据库范围的配置、跟踪标志或其他查询提示(例如QUERY_OPTIMIZER_COMPATIBILITY_LEVEL_n)强制设置,提示QUERYTRACEON不会替代默认或旧基数估计设置。 此提示仅影响查询优化器的行为。 它不会影响可能依赖于 数据库兼容性级别的 SQL Server 的其他功能,例如某些数据库功能的可用性。 有关详细信息,请参阅 开发人员的选择:提示查询执行模型

2 如果启用收集 query_post_execution_showplan 扩展事件,则会将标准分析基础结构添加到服务器上运行的每个查询,因此可能会影响服务器的整体性能。 如果启用扩展事件的集合 query_thread_profile 以改用轻型分析基础结构,这会导致性能开销要小得多,但仍会影响服务器的整体性能。 如果启用 query_plan_profile 扩展事件,则只会为随该 query_plan_profile 事件一起执行的查询启用轻型分析基础结构,因此不会影响服务器上的其他工作负荷。 使用此提示分析特定查询,而不会影响服务器工作负荷的其他部分。 有关轻型分析的详细信息,请参阅 查询分析基础结构

可以使用动态管理视图USE HINT查询所有支持的名称的列表。

重要

某些 USE HINT 提示可能与在全局级别或会话级别启用的跟踪标志或数据库范围的配置设置冲突。 在这种情况下,查询级别提示 (USE HINT) 始终优先。 USE HINT如果与另一个查询提示冲突,或查询级别(如 byQUERYTRACEON)启用的跟踪标志,则尝试执行查询时,SQL Server 将生成错误。

使用计划 N'xml_plan'

强制查询优化器对 由xml_plan指定的查询使用现有查询计划。

此功能强制生成的执行计划与强制计划相同或类似。 由于生成的计划可能与指定的 USE PLAN计划不同,因此计划的性能可能会有所不同。 在极少数情况下,性能差异可能很大且为负;在这种情况下,管理员必须删除强制计划。

TABLE HINT ( exposed_object_name [ , <table_hint> [ , ] ...n ] ]

将指定的表提示应用于与 exposed_object_name对应的表或视图。 我们建议仅在计划指南的上下文中将表提示用作查询提示。

exposed_object_name 可以是以下引用之一:

  • 当别名用于查询的 FROM 子句中的表或视图时, exposed_object_name 是别名。

  • 不使用别名时, exposed_object_name与 子句中 FROM 引用的表或视图完全匹配。 例如,如果使用两部分名称引用表或视图, 则exposed_object_name 是相同的两部分名称。

如果在未指定表提示的情况下指定 exposed_object_name ,则忽略在查询中指定为对象表提示的一部分的任何索引。 然后,查询优化器确定索引使用情况。 当无法修改原始查询时,可以使用此方法消除表提示的效果 INDEX 。 请参阅 示例 J

<table_hint>

NOEXPAND [ , INDEX ( index_value [ ,...n ] | |INDEX = ( index_value ) ] |INDEX ( index_value [ ,...n ] | |INDEX = ( index_value ) |FORCESEEK [ ( index_value ( index_column_name [ ,... ] ) ] | |FORCESCAN |HOLDLOCK |NOLOCK |NOWAIT |PAGLOCK |READCOMMITTED |READCOMMITTEDLOCK |READPAST |READUNCOMMITTED |REPEATABLEREAD |ROWLOCK |SERIALIZABLE |SNAPSHOT |SPATIAL_WINDOW_MAX_CELLS = integer_value |TABLOCK |TABLOCKX |UPDLOCK |XLOCK

要应用于作为查询提示 exposed_object_name 的表或视图的表提示。 有关这些提示的说明,请参阅 表提示

除其他表提示外INDEXFORCESCAN,不允许FORCESEEK作为查询提示,除非查询已有指定WITH表提示的子句。 有关详细信息,请参阅 “备注”部分

谨慎

FORCESEEK使用参数进行指定会限制查询优化器可以考虑的计划数,而不是在指定FORCESEEK不使用参数时考虑的计划数。 这可能会导致在更多情况下出现“无法生成计划”错误。

时间戳为“point_in_time

适用于:Microsoft Fabric 数据仓库

TIMESTAMP使用子句中的OPTION语法查询过去存在的数据,这是 Microsoft Fabric 中 Synapse 数据仓库中的一部分时间旅行功能。

指定格式point_in_timeyyyy-MM-ddTHH:mm:ss[.fff]以返回当时显示的数据。 时区始终采用 UTC 格式。 使用CONVERT样式为 126 的必要日期/时间格式的语法。

TIMESTAMP AS OF只能使用OPTION子句指定提示一次。 有关详细信息和限制,请参阅 过去存在的查询数据

FORCE [ 单节点 |DISTRIBUTED ] PLAN

适用于:Microsoft Fabric 数据仓库

允许用户选择是强制执行单个节点计划还是强制执行分布式计划。

注解

查询提示不能在语句中 INSERT 指定,但语句中使用子句时 SELECT 除外。

查询提示只能在顶级查询中指定,而不能在子查询中指定。 将表提示指定为查询提示时,可以在顶级查询或子查询中指定提示。 但是,为子句中TABLE HINT指定的值必须与查询或子查询中公开的名称完全匹配。

将表提示指定为查询提示

建议INDEX仅在FORCESCAN的上下文中使用或FORCESEEK表提示作为查询提示。 例如,当无法修改原始查询时,计划指南非常有用,因为它是第三方应用程序。 在编译和优化查询之前,计划指南中指定的查询提示将添加到查询中。 对于即席查询,仅在测试计划指南语句时使用 TABLE HINT 子句。 对于所有其他即席查询,建议仅将这些提示指定为表提示。

指定为查询提示时,INDEXFORCESCANFORCESEEK表提示对以下对象有效:

  • 表格
  • 浏览量
  • 索引视图
  • 公用表表达式(必须在结果集填充公共表表达式的语句中 SELECT 指定提示)
  • 动态管理视图 (DMV)
  • 命名子查询

可以为没有任何现有表提示的查询指定 INDEXFORCESCAN表提示和 FORCESEEK 表提示。 还可以使用它们分别替换查询中的现有INDEXFORCESCANFORCESEEK或提示。

除其他表提示外INDEXFORCESCAN,不允许FORCESEEK作为查询提示,除非查询已有指定WITH表提示的子句。 在这种情况下,还必须将匹配提示指定为查询提示。 使用 TABLE HINT 子句将 OPTION 匹配提示指定为查询提示。 此规范保留查询的语义。 例如,如果查询包含表提示 NOLOCKOPTION 则计划指南 的 @hints 参数中的子句还必须包含 NOLOCK 提示。 请参阅 示例 K

使用查询存储提示指定提示

可以使用 查询存储提示 功能对通过查询存储标识的查询强制执行提示,而无需更改代码。 使用 sys.sp_query_store_set_hints 存储过程向查询应用提示。 请参阅示例 N。

Fabric 数据仓库中的查询提示支持

Microsoft Fabric 数据仓库 支持查询提示的子集:

  • HASH GROUP
  • ORDER GROUP
  • MERGE UNION
  • HASH UNION
  • CONCAT UNION
  • FORCE ORDER
  • USE HINT
    • ASSUME_MIN_SELECTIVITY_FOR_FILTER_ESTIMATES
    • ASSUME_FULL_INDEPENDENCE_FOR_FILTER_ESTIMATES
    • ASSUME_PARTIAL_CORRELATION_FOR_FILTER_ESTIMATES
    • ASSUME_JOIN_PREDICATE_DEPENDS_ON_FILTERS

这些查询提示专用于Microsoft Fabric 数据仓库:

  • FORCE SINGLE NODE PLANFORCE DISTRIBUTED PLAN

例子

答: 使用 MERGE JOIN

以下示例指定 MERGE JOIN 在查询中运行 JOIN 作。 该示例使用 AdventureWorks2022 数据库。

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

以下示例指示查询优化器使用值'Seattle'@city_name,并在优化查询时对所有@postal_code列值使用谓词的平均选择性。 该示例使用 AdventureWorks2022 数据库。

CREATE PROCEDURE dbo.RetrievePersonAddress
@city_name NVARCHAR(30),
@postal_code NVARCHAR(15)
AS
SELECT * FROM Person.Address
WHERE City = @city_name AND PostalCode = @postal_code
OPTION ( OPTIMIZE FOR (@city_name = 'Seattle', @postal_code UNKNOWN) );
GO

C. 使用 MAXRECURSION

MAXRECURSION 可用于防止格式不佳的递归公共表表达式进入无限循环。 以下示例有意创建无限循环,并使用 MAXRECURSION 提示将递归级别数限制为 2。 该示例使用 AdventureWorks2022 数据库。

--Creates an infinite loop
WITH cte (CustomerID, PersonID, StoreID) AS
(
    SELECT CustomerID, PersonID, StoreID
    FROM Sales.Customer
    WHERE PersonID IS NOT NULL
  UNION ALL
    SELECT cte.CustomerID, cte.PersonID, cte.StoreID
    FROM cte
    JOIN  Sales.Customer AS e
        ON cte.PersonID = e.CustomerID
)
--Uses MAXRECURSION to limit the recursive levels to 2
SELECT CustomerID, PersonID, StoreID
FROM cte
OPTION (MAXRECURSION 2);
GO

更正编码错误后, MAXRECURSION 不再需要。

D. 使用 MERGE UNION

以下示例使用 MERGE UNION 查询提示。 该示例使用 AdventureWorks2022 数据库。

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

E. 使用 HASH GROUP 和 FAST

以下示例使用 HASH GROUPFAST 查询提示。 该示例使用 AdventureWorks2022 数据库。

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 查询提示。 该示例使用 AdventureWorks2022 数据库。

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

G. 使用 INDEX

以下示例使用 INDEX 提示。 第一个示例指定单个索引。 第二个示例指定单个表引用的多个索引。 在这两个示例中,由于对使用别名的表应用 INDEX 提示,因此 TABLE HINT 子句还必须指定与公开的对象名称相同的别名。 该示例使用 AdventureWorks2022 数据库。

EXEC sp_create_plan_guide
    @name = N'Guide1',
    @stmt = N'SELECT c.LastName, c.FirstName, e.Title
              FROM HumanResources.Employee AS e
              JOIN Person.Contact AS c ON e.ContactID = c.ContactID
              WHERE e.ManagerID = 2;',
    @type = N'SQL',
    @module_or_batch = NULL,
    @params = NULL,
    @hints = N'OPTION (TABLE HINT(e, INDEX (IX_Employee_ManagerID)))';
GO
EXEC sp_create_plan_guide
    @name = N'Guide2',
    @stmt = N'SELECT c.LastName, c.FirstName, e.Title
              FROM HumanResources.Employee AS e
              JOIN Person.Contact AS c ON e.ContactID = c.ContactID
              WHERE e.ManagerID = 2;',
    @type = N'SQL',
    @module_or_batch = NULL,
    @params = NULL,
    @hints = N'OPTION (TABLE HINT(e, INDEX(PK_Employee_EmployeeID, IX_Employee_ManagerID)))';
GO

H. 使用 FORCESEEK

以下示例使用 FORCESEEK 表提示。 该 TABLE HINT 子句还必须指定与公开的对象名称相同的两部分名称。 在对使用两部分名称的表应用 INDEX 提示时指定名称。 该示例使用 AdventureWorks2022 数据库。

EXEC sp_create_plan_guide
    @name = N'Guide3',
    @stmt = N'SELECT c.LastName, c.FirstName, HumanResources.Employee.Title
              FROM HumanResources.Employee
              JOIN Person.Contact AS c ON HumanResources.Employee.ContactID = c.ContactID
              WHERE HumanResources.Employee.ManagerID = 3
              ORDER BY c.LastName, c.FirstName;',
    @type = N'SQL',
    @module_or_batch = NULL,
    @params = NULL,
    @hints = N'OPTION (TABLE HINT( HumanResources.Employee, FORCESEEK))';
GO

一。 使用多个表提示

以下示例将 INDEX 提示应用于一个表,并将 FORCESEEK 提示应用于另一个表。 该示例使用 AdventureWorks2022 数据库。

EXEC sp_create_plan_guide
    @name = N'Guide4',
    @stmt = N'SELECT e.ManagerID, c.LastName, c.FirstName, e.Title
              FROM HumanResources.Employee AS e
              JOIN Person.Contact AS c ON e.ContactID = c.ContactID
              WHERE e.ManagerID = 3;',
    @type = N'SQL',
    @module_or_batch = NULL,
    @params = NULL,
    @hints = N'OPTION (TABLE HINT (e, INDEX( IX_Employee_ManagerID))
                       , TABLE HINT (c, FORCESEEK))';
GO

J. 使用 TABLE HINT 替代现有表提示

以下示例演示如何使用 TABLE HINT 提示。 可以使用提示而不指定提示来替代 INDEX 在查询子句中指定的 FROM 表提示行为。 该示例使用 AdventureWorks2022 数据库。

EXEC sp_create_plan_guide
    @name = N'Guide5',
    @stmt = N'SELECT e.ManagerID, c.LastName, c.FirstName, e.Title
              FROM HumanResources.Employee AS e WITH (INDEX (IX_Employee_ManagerID))
              JOIN Person.Contact AS c ON e.ContactID = c.ContactID
              WHERE e.ManagerID = 3;',
    @type = N'SQL',
    @module_or_batch = NULL,
    @params = NULL,
    @hints = N'OPTION (TABLE HINT(e))';
GO

K. 指定影响语义的表提示

以下示例在查询中包含两个表提示: NOLOCK即语义影响,以及 INDEX非语义影响。 若要保留查询的语义,在 NOLOCK 计划指南的子句中 OPTIONS 指定提示。 除了 NOLOCK 提示,指定 INDEX 提示 FORCESEEK ,并在语句编译和优化期间替换查询中的非语义影响 INDEX 提示。 该示例使用 AdventureWorks2022 数据库。

EXEC sp_create_plan_guide
    @name = N'Guide6',
    @stmt = N'SELECT c.LastName, c.FirstName, e.Title
              FROM HumanResources.Employee AS e
                   WITH (NOLOCK, INDEX (PK_Employee_EmployeeID))
              JOIN Person.Contact AS c ON e.ContactID = c.ContactID
              WHERE e.ManagerID = 3;',
    @type = N'SQL',
    @module_or_batch = NULL,
    @params = NULL,
    @hints = N'OPTION (TABLE HINT (e, INDEX(IX_Employee_ManagerID), NOLOCK, FORCESEEK))';
GO

以下示例演示了一种替代方法,用于保留查询的语义,并允许优化器选择表提示中指定的索引以外的索引。 允许优化器通过在子句中NOLOCK指定OPTIONS提示来选择。 指定提示,因为它会影响语义。 然后, TABLE HINT 仅指定包含表引用的关键字,并且没有 INDEX 提示。 该示例使用 AdventureWorks2022 数据库。

EXEC sp_create_plan_guide
    @name = N'Guide7',
    @stmt = N'SELECT c.LastName, c.FirstName, e.Title
              FROM HumanResources.Employee AS e
                   WITH (NOLOCK, INDEX (PK_Employee_EmployeeID))
              JOIN Person.Contact AS c ON e.ContactID = c.ContactID
              WHERE e.ManagerID = 2;',
    @type = N'SQL',
    @module_or_batch = NULL,
    @params = NULL,
    @hints = N'OPTION (TABLE HINT (e, NOLOCK))';
GO

L. Use USE HINT

以下示例使用 RECOMPILEUSE HINT 查询提示。 该示例使用 AdventureWorks2022 数据库。

SELECT * FROM Person.Address
WHERE City = 'SEATTLE' AND PostalCode = 98104
OPTION (RECOMPILE, USE HINT ('ASSUME_MIN_SELECTIVITY_FOR_FILTER_ESTIMATES', 'DISABLE_PARAMETER_SNIFFING'));
GO

M. 使用 QUERYTRACEON 提示

以下示例使用 QUERYTRACEON 查询提示。 该示例使用 AdventureWorks2022 数据库。 可以使用以下查询为特定查询启用跟踪标志 4199 控制的所有影响计划的修补程序:

SELECT * FROM Person.Address
WHERE City = 'SEATTLE' AND PostalCode = 98104
OPTION (QUERYTRACEON 4199);

还可以使用多个跟踪标志,如以下查询所示:

SELECT * FROM Person.Address
WHERE City = 'SEATTLE' AND PostalCode = 98104
OPTION  (QUERYTRACEON 4199, QUERYTRACEON 4137);

N. 使用查询存储提示

查询存储提示功能提供了一种易于使用的方法,用于在不更改应用程序代码的情况下调整查询计划。

首先,标识已在查询存储目录视图中执行的查询,例如:

SELECT q.query_id, qt.query_sql_text
FROM sys.query_store_query_text qt
INNER JOIN sys.query_store_query q ON
    qt.query_text_id = q.query_text_id
WHERE query_sql_text like N'%ORDER BY ListingPrice DESC%'
  AND query_sql_text not like N'%query_store%';
GO

以下示例应用提示以强制 旧基数估算器 query_id 39,在查询存储中标识:

EXEC sys.sp_query_store_set_hints @query_id = 39, @query_hints = N'OPTION (USE HINT (''FORCE_LEGACY_CARDINALITY_ESTIMATION''))';

以下示例应用提示,以强制实施最大内存授予大小(在配置的内存限制PERCENTquery_id 39,在查询存储中标识):

EXEC sys.sp_query_store_set_hints @query_id = 39, @query_hints = N'OPTION (MAX_GRANT_PERCENT = 10)';

以下示例将多个查询提示应用于query_id 39,包括 RECOMPILEMAXDOP 1SQL Server 2012 (11.x) 查询优化器行为:

EXEC sys.sp_query_store_set_hints @query_id = 39,
    @query_hints = N'OPTION(RECOMPILE, MAXDOP 1, USE HINT (''QUERY_OPTIMIZER_COMPATIBILITY_LEVEL_110''))';

以下示例通过应用 ABORT_QUERY_EXECUTION 提示,阻止使用 query_id 39 的查询从将来执行。 提示处于预览状态。

EXEC sys.sp_query_store_set_hints @query_id = 39,
    @query_hints = N'OPTION (USE HINT (''ABORT_QUERY_EXECUTION''))';

O. 从时间点开始查询数据

适用于:Microsoft Fabric 中的仓库

TIMESTAMP使用子句中的OPTION语法在 Microsoft Fabric 的 Synapse 数据仓库中查询过去存在的数据。 以下示例查询在 2024 年 3 月 13 日下午 7:39:35.28 UTC 显示时返回数据。 时区始终采用 UTC 格式。

SELECT OrderDateKey, SUM(SalesAmount) AS TotalSales
FROM FactInternetSales
GROUP BY OrderDateKey
ORDER BY OrderDateKey
OPTION (FOR TIMESTAMP AS OF '2024-03-13T19:39:35.28');--March 13, 2024 at 7:39:35.28 PM UTC