查詢提示 (Transact-SQL)
適用於:SQL Server
Azure SQL 資料庫 Azure SQL 受控執行個體
查詢提示會指定在查詢範圍中使用指定的提示。 查詢提示會影響陳述式中的所有運算子。 如果 UNION
涉及主要查詢,則只有涉及作業的最後一個 UNION
查詢可以有 OPTION
子句。 查詢提示是在 OPTION 子句中指定。 如果一或多個查詢提示造成查詢最佳化工具不會產生有效的計劃,就會產生 8622 錯誤。
警告
由於 SQL Server 查詢最佳化工具通常會選擇最好的查詢執行計劃;因此,建議資深開發人員與資料庫管理員只在必要情況使用提示。
適用範圍:
Syntax
<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 ( <use_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
}
<use_hint_name> ::=
{ 'ASSUME_JOIN_PREDICATE_DEPENDS_ON_FILTERS'
| 'ASSUME_MIN_SELECTIVITY_FOR_FILTER_ESTIMATES'
| 'ASSUME_FULL_INDEPENDENCE_FOR_FILTER_ESTIMATES'
| 'ASSUME_PARTIAL_CORRELATION_FOR_FILTER_ESTIMATES'
| 'DISABLE_BATCH_MODE_ADAPTIVE_JOINS'
| 'DISABLE_BATCH_MODE_MEMORY_GRANT_FEEDBACK'
| 'DISABLE_DEFERRED_COMPILATION_TV'
| 'DISABLE_INTERLEAVED_EXECUTION_TVF'
| 'DISABLE_OPTIMIZED_NESTED_LOOP'
| 'DISABLE_OPTIMIZER_ROWGOAL'
| 'DISABLE_PARAMETER_SNIFFING'
| 'DISABLE_ROW_MODE_MEMORY_GRANT_FEEDBACK'
| 'DISABLE_TSQL_SCALAR_UDF_INLINING'
| 'DISALLOW_BATCH_MODE'
| 'ENABLE_HIST_AMENDMENT_FOR_ASC_KEYS'
| 'ENABLE_QUERY_OPTIMIZER_HOTFIXES'
| 'FORCE_DEFAULT_CARDINALITY_ESTIMATION'
| 'FORCE_LEGACY_CARDINALITY_ESTIMATION'
| 'QUERY_OPTIMIZER_COMPATIBILITY_LEVEL_n'
| 'QUERY_PLAN_PROFILE'
}
注意
若要檢視 SQL Server 2014 (12.x) 和更早版本的 Transact-SQL 語法,請參閱舊版文件。
引數
{ HASH | ORDER } GROUP
指定查詢或DISTINCT
子句描述的GROUP BY
匯總應該使用哈希或排序。
{ MERGE | HASH | CONCAT } UNION
指定所有 UNION
作業都是透過合併、哈希或串 UNION
連集來執行。 如果指定了多個 UNION
提示,查詢優化器會從指定的提示中選取成本最低的策略。
{ LOOP | MERGE | HASH } JOIN
指定所有聯結作業都是由 LOOP JOIN
、 MERGE JOIN
或 HASH JOIN
在整個查詢中執行。 如果您指定多個聯結提示,最佳化工具會從允許使用的聯結提示中,選取成本最低的聯結策略。
如果您在特定數據表組的相同查詢 FROM
子句中指定聯結提示,這個聯結提示優先於兩個數據表的聯結。 不過,必須仍然能夠接受這些查詢提示。 這組資料表的聯結提示可能只會限制查詢提示中所允許使用聯結方法的選取。 如需詳細資訊,請參閱 聯結提示。
DISABLE_OPTIMIZED_PLAN_FORCING
適用於:SQL Server (從 SQL Server 2022 (16.x) 開始)
停用查詢的最佳化計劃強制執行。
最佳化計劃強制執行可減少重複強制查詢所產生的編譯負荷。 產生查詢執行計劃之後,系統會儲存特定的編譯步驟,以最佳化重新執行指令碼的形式重複使用。 最佳化重新執行指令碼會在查詢存放區中儲存為壓縮的執行程序表 XML 的一部分,位於隱藏的 OptimizationReplay
屬性中。
EXPAND VIEWS
指定展開索引檢視表。 另外,指定查詢最佳化工具不會考慮使用任何索引檢視表來作為任何查詢組件的取代項目。 當檢視表定義取代查詢文字中的檢視表名稱時,便會展開這份檢視表。
這個查詢提示會虛擬地禁止直接在查詢計畫中使用索引檢視表及其索引。
注意
如果查詢部分有檢視的 SELECT
直接參考,索引檢視會保持壓縮。 如果您指定 WITH (NOEXPAND)
或 WITH (NOEXPAND, INDEX( <index_value> [ , *...n* ] ) )
,檢視也會維持壓縮狀態。 如需查詢提示 NOEXPAND
的詳細資訊,請參閱 使用 NOEXPAND。
提示只會影響 語句SELECT
部分的檢視,包括 、 UPDATE
MERGE
和 DELETE
語句中的INSERT
這些檢視。
FAST integer_value
指定將查詢最佳化,以快速擷取前 integer_value 個資料列。 此結果為非負整數。 傳回前 integer_value 個資料列之後,查詢會繼續執行並產生完整的結果集。
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 PLAN
強制查詢最佳化工具不因統計資料中的變更而重新編譯查詢。 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
記憶體授與大小上限。 如果在使用者定義的資源集區中執行查詢,則查詢保證不會超過此限制。 在此情況下,如果查詢沒有所需的最小記憶體,系統就會引發錯誤。 如果在系統集區 (預設) 中執行查詢,則至少會取得執行所需的記憶體。 如果 Resource Governor 設定低於此提示所指定的值,實際限制可能更低。 有效值介於 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 Database。
覆寫 sp_configure
的 max degree of parallelism 設定選項。 也會針對指定這個選項的查詢覆寫 Resource Governor。 查詢 MAXDOP
提示可能超過使用 sp_configure
設定的值。 如果MAXDOP
超過使用 Resource Governor 設定的值,資料庫引擎 會使用 ALTER WORKLOAD GROUP 中所述的資源管理員MAXDOP
值。 當您使用MAXDOP
查詢提示時,所有搭配 max degree of parallelism 組態選項使用的語意規則都適用。 如需詳細資訊,請參閱 設定 max degree of parallelism 伺服器組態選項。
警告
如果 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 Database。
防止多工緩衝處理運算子加入查詢計劃 (需有多工緩衝處理才能保證有效的更新語意的計劃除外)。 在某些情況下,多工緩衝處理運算子會降低效能。 例如,多工緩衝處理會使用 tempdb
,因此如果有許多並行查詢與多工緩衝處理作業一起執行,可能會發生 tempdb
競爭。
OPTIMIZE FOR ( @variable_name { UNKNOWN | = <literal_constant> } [ , ...n ] )
指示查詢最佳化工具在查詢進行編譯和最佳化時,使用特定的區域變數值。 只有在查詢最佳化期間,才使用這個值,在查詢執行期間,不使用這個值。
@variable_name
查詢中使用的局部變數名稱,值可以指派給查詢提示以搭配
OPTIMIZE FOR
使用。UNKNOWN
指定查詢最佳化工具使用統計資料 (而非初始值) 來判斷查詢最佳化期間的區域變數值。
literal_constant
要指派 給常值@variable_name 常值,以便與查詢提示搭配
OPTIMIZE 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
查詢提示只能在計劃指南內指定,以覆寫資料庫SET
選項的PARAMETERIZATION
目前設定。 您不能在查詢中直接指定它。
如需詳細資訊,請參閱使用計劃指南指定查詢參數化行為。
SIMPLE
指示查詢優化器嘗試簡單的參數化。 FORCED
指示查詢優化器嘗試強制參數化。 如需詳細資訊,請參閱查詢處理架構指南中的強制參數化和查詢處理架構指南中的簡單參數化。
QUERYTRACEON <integer_value>
此選項可讓您只在單一查詢編譯期間啟用影響計劃的追蹤旗標。 如同其他查詢層級的選項,您可以將此選項與計畫指南一起使用,以便比對任何工作階段所執行查詢的文字,並在編譯此查詢時,自動套用影響計畫的追蹤旗標。 QUERYTRACEON
只有查詢優化器追蹤旗標才支援此選項。 如需詳細資訊,請參閱追蹤旗標。
如果使用不支援的追蹤旗標編號,使用此選項並不會傳回任何錯誤或警告。 如果指定的追蹤旗標不是影響查詢執行計劃的追蹤旗標,則會以無訊息方式忽略此選項。
若要在查詢中使用多個追蹤旗標,請為每個不同的追蹤旗標編號指定一個 QUERYTRACEON
提示。
RECOMPILE
指示 SQL Server 資料庫引擎針對查詢產生新的暫時計劃,並在查詢完成執行之後立即捨棄該計劃。 當相同的查詢在沒有提示的情況下執行 RECOMPILE
時,產生的查詢計劃不會取代儲存在快取中的計劃。 若未指定 RECOMPILE
,資料庫引擎 會快取查詢計劃並重複使用它們。 編譯查詢計劃時, RECOMPILE
查詢提示會使用查詢中任何局部變數的目前值。 如果查詢是在預存程序內,則將目前值傳遞給任何參數。
RECOMPILE
是建立預存程序的實用替代方案。 RECOMPILE
WITH RECOMPILE
只有在預存程式內的查詢子集而非整個預存程式必須重新編譯時,才會使用 子句。 如需詳細資訊,請參閱重新編譯預存程序。 RECOMPILE
當您建立計劃指南時,也很有用。
ROBUST PLAN
強制查詢最佳化工具嘗試一項適用於最大潛在資料列大小的計劃,可能會犧牲效能。 當處理查詢時,中繼資料表和運算子可能需要儲存和處理比任何輸入資料列還寬的資料列。 這些資料列的寬度,有時可能會使特定運算子無法處理資料列。 如果資料列具有該寬度,資料庫引擎會在查詢執行期間產生錯誤。 藉由使用 ROBUST PLAN
,您可以指示查詢優化器不要考慮任何可能遇到此問題的查詢計劃。
如果無法執行這類計劃,則查詢最佳化工具會傳回錯誤,而不是將錯誤偵測延遲到查詢執行時。 資料列會包含變動長度資料行;資料庫引擎允許資料列定義成超出資料庫引擎處理能力的最大潛在大小。 一般而言,雖然有最大潛在大小,但應用程式仍會儲存實際大小在資料庫引擎處理能力限制之內的資料列。 如果資料庫引擎遇到太長的資料列,便會傳回執行錯誤。
USE HINT ( 'hint_name' )
適用於:SQL Server (從 SQL Server 2016 (13.x) SP1 開始) 與 Azure SQL Database。
提供查詢處理器的一或多個額外提示。 額外的提示會以單引號內的提示名稱指定。
提示
提示名稱不區分大小寫。
支援下列提示名稱:
提示 | 描述 |
---|---|
'ASSUME_JOIN_PREDICATE_DEPENDS_ON_FILTERS' |
在 SQL Server 2014 (12.x) 和更新版本的查詢優化器 基數估計 模型下,使用簡單內含專案假設來產生查詢計劃,而不是聯結的預設基底內含專案假設。 此提示名稱相當於 追蹤旗標 9476。 |
'ASSUME_MIN_SELECTIVITY_FOR_FILTER_ESTIMATES' |
導致 SQL Server 在評估篩選條件的 AND 述詞在完整相互關聯中的占比時,使用最小選擇性產生計劃。 當搭配 SQL Server 2012 (11.x) 和舊版的基數估計模型使用時,此提示名稱相當於追蹤旗標 4137,而且當追蹤旗標 9471 與 SQL Server 2014 (12.x) 和更新版本的基數估計模型搭配使用時,具有類似的效果。 |
'ASSUME_FULL_INDEPENDENCE_FOR_FILTER_ESTIMATES' |
導致 SQL Server 在評估篩選條件的 AND 述詞在完整獨立性中的占比時,使用最大選擇性產生計劃。 此提示名稱是 SQL Server 2012 (11.x) 和舊版基數估計模型的預設行為,相當於 搭配 SQL Server 2014 (12.x) 和更新版本的基數估計模型使用時追蹤旗標 9472。 適用於:Azure SQL Database |
'ASSUME_PARTIAL_CORRELATION_FOR_FILTER_ESTIMATES' |
導致 SQL Server 在評估篩選條件的 AND 述詞在完整相互關聯中的占比時,使用從最多到最少的選擇性產生計劃。 此提示名稱是 SQL Server 2014 (12.x) 和更新版本基數估計模型的預設行為。 適用於:Azure SQL Database |
'DISABLE_BATCH_MODE_ADAPTIVE_JOINS' |
停用批次模式自適性聯結。 如需詳細資訊,請參閱批次模式自適性聯結。 適用於:SQL Server 2017 (14.x) 和更新版本,以及 Azure SQL 資料庫 |
'DISABLE_BATCH_MODE_MEMORY_GRANT_FEEDBACK' |
停用批次模式記憶體授與意見反應。 如需詳細資訊,請參閱批次模式記憶體授與意見反應。 適用於: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_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_QUERY_OPTIMIZER_HOTFIXES' |
啟用查詢最佳化工具 Hotfix (在 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
執行的查詢啟用輕量型分析基礎結構,因此不會影響伺服器上的其他工作負載。 使用提示分析特定查詢,而不影響伺服器工作負載的其他部分。 如需輕量型分析的詳細資訊,請參閱 查詢分析基礎結構。
您可以使用動態管理檢視sys.dm_exec_valid_use_hints來查詢所有支援USE HINT
的名稱清單。
重要
某些 USE HINT
提示可能會與全域或會話層級或資料庫範圍組態設定上啟用的追蹤旗標發生衝突。 在此情況下,查詢層級提示 (USE HINT
) 一律優先。 如果與 USE HINT
另一個查詢提示發生衝突,或查詢層級啟用的追蹤旗標(例如 by QUERYTRACEON
),SQL Server 會在嘗試執行查詢時產生錯誤。
USE PLAN N'xml_plan'
強制查詢優化器針對xml_plan所指定的查詢使用現有的查詢計劃。 USE PLAN
無法使用 、、 UPDATE
MERGE
或 DELETE
語句來指定INSERT
。
這項功能所強制產生的執行計劃與強制執行計劃相同或類似。 由於產生的計劃可能與 所 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做為查詢提示之數據表或檢視表的數據表提示。 如需這些提示的描述,請參閱 數據表提示。
除了 、 FORCESCAN
和 FORCESEEK
以外的INDEX
數據表提示,除非查詢已經有WITH
指定數據表提示的子句,否則不允許做為查詢提示。 如需詳細資訊,請參閱備註一節。
警告
使用 FORCESEEK
參數指定會限制查詢優化器可考慮的計劃數目,而不是在指定不含參數時 FORCESEEK
考慮的計劃數目。 這可能會導致在許多狀況下發生「無法產生計畫」錯誤。
FOR TIMESTAMP AS OF 'point_in_time'
適用於:Microsoft Fabric 的倉儲
使用 OPTION
子句中的 TIMESTAMP
語法來查詢過去存在的資料,這是 Microsoft Fabric 中 Synapse 資料倉儲的時間旅行功能的一部分。
以格式 yyyy-MM-ddTHH:mm:ss[.fff]
指定 point_in_time,即會傳回當時出現的資料。 時區一律為 UTC。 使用 CONVERT
語法,以取得具有樣式 126 的必要日期時間格式。
TIMESTAMP AS OF
提示只能使用 OPTION
子句指定一次。 如需詳細資訊和限制,請參閱查詢過去存在的資料。
備註
查詢提示不能在語句中 INSERT
指定,但語句內使用 子句時 SELECT
除外。
您只能在最上層查詢中指定查詢提示,不能在子查詢中指定查詢提示。 當資料表提示指定為查詢提示時,可以在最上層查詢或子查詢中指定提示。 不過,子句中TABLE HINT
針對 exposed_object_name 指定的值必須完全符合查詢或子查詢中公開的名稱。
將資料表提示指定為查詢提示
我們建議INDEX
只在計劃指南的內容中使用、 FORCESCAN
或 FORCESEEK
數據表提示作為查詢提示。 當您無法修改原始的查詢 (例如,因為它是協力廠商應用程式) 時,計畫指南就很有用。 在編譯並優化之前,計劃指南中指定的查詢提示會新增至查詢。 針對臨機操作查詢,只有在測試計劃指南語句時,才使用 TABLE HINT
子句。 若是其他隨選查詢,建議您將這些提示只指定為資料表提示。
指定為查詢提示時, INDEX
、 FORCESCAN
資料 FORCESEEK
表提示對下列物件有效:
- 資料表
- 檢視
- 索引檢視
- 通用資料表表示式(必須在結果集填入通用資料表表達式的語句中
SELECT
指定提示) - 動態管理檢視 (DMV)
- 具名子查詢
您可以將、 FORCESCAN
與 FORCESEEK
資料表提示指定INDEX
為沒有任何現有資料表提示之查詢的查詢提示。 您也可以使用它們分別取代查詢中的現有 INDEX
、 FORCESCAN
或 FORCESEEK
提示。
除了 、 FORCESCAN
和 FORCESEEK
以外的INDEX
數據表提示,除非查詢已經有WITH
指定數據表提示的子句,否則不允許做為查詢提示。 在此情況下,還必須指定相符的提示作為查詢提示。 在 子句中使用 OPTION
,將比對提示指定為查詢提示TABLE HINT
。 此規格會保留查詢的語意。 例如,如果查詢包含數據表提示NOLOCK
,OPTION
則計劃指南之 @hints 參數中的 子句也必須包含NOLOCK
提示。 請參閱 範例 K。
使用查詢存放區提示指定提示
您可以使用查詢存放區提示功能,對透過查詢存放區識別的查詢強制執行提示,而不進行程式碼變更。 使用 sys.sp_query_store_set_hints 預存程序將提示套用至查詢。 請參閱範例 N。
範例
A. 使用 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 GROUP
和 FAST
查詢提示。 此範例會使用 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
I. 使用多個資料表提示
下列範例會將 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
下列範例示範另一個方法來保留查詢的語意,並讓最佳化工具選擇使用不是資料表提示中所指定的索引。 允許優化器藉由在 子句中OPTIONS
指定NOLOCK
提示來選擇。 您會指定此提示,因為它會影響語意。 然後,只指定 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 HINT
下列範例使用 RECOMPILE
和 USE 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 HINT
下列範例使用 QUERYTRACEON
查詢提示。 此範例會使用 AdventureWorks2022
資料庫。 您可以使用下列查詢,針對特定查詢啟用由追蹤旗標 4199 所控制所有影響計畫的 Hotfix:
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. 使用查詢存放區提示
Azure SQL Database 中的查詢存放區提示功能提供容易使用的查詢計劃製作方法,不需要變更應用程式的程式碼。
首先,找出已在查詢存放區目錄檢視中執行的查詢,例如:
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''))';
下列範例會套用提示,以在已設定的記憶體限制中PERCENT
強制執行記憶體授與大小上限為 query_id
39,如 查詢存放區 所示:
EXEC sys.sp_query_store_set_hints @query_id= 39, @query_hints = N'OPTION(MAX_GRANT_PERCENT=10)';
下列範例會將多個查詢提示套用至 query_id 39,包括 RECOMPILE
、 MAXDOP 1
和 SQL 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''))';
O. 查詢某個時間點的資料
適用於:Microsoft Fabric 的倉儲
在 Microsoft Fabric 中 Synapse 資料倉儲中,使用 OPTION
子句中的 TIMESTAMP
語法來查詢過去存在的資料。 下列範例查詢會傳回時間點為 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