共用方式為


查詢提示 (Transact-SQL)

適用於:SQL ServerAzure SQL 資料庫Azure SQL 受控執行個體Microsoft Fabric 中的 SQL 分析端點Microsoft Fabric 中的倉儲Microsoft Fabric 中的 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 ( <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'
}

論點

{ HASH |ORDER } GROUP

指定查詢 GROUP BYDISTINCT 子句描述的匯總應該使用哈希或排序。

  • 一般而言,哈希型演算法可以改善涉及大型或複雜群組集的查詢效能。
  • 一般而言,以排序為基礎的演算法可以改善涉及小型或簡單群組集的查詢效能。

{ MERGE |HASH |CONCAT } UNION

指定所有 UNION 作業都是藉由合併、哈希或串連 UNION 集來執行。 如果指定了多個 UNION 提示,查詢優化器會從指定的提示中選取成本最低的策略。

  • 一般而言,合併式演算法作業可以改善涉及已排序輸入的查詢效能。
  • 一般而言,哈希型演算法可以改善涉及未排序或大型輸入的查詢效能。
  • 一般而言,串連型演算法可以改善涉及不同或小型輸入的查詢效能。

{ LOOP |MERGE |HASH } JOIN

指定所有聯結作業都是由整個查詢中的 LOOP JOINMERGE JOINHASH JOIN 來執行。 如果您指定多個聯結提示,優化器會從允許的聯結策略中選取成本最低的聯結策略。

如果您在相同查詢的 FROM 子句中指定特定數據表組的聯結提示,這個聯結提示優先於兩個數據表的聯結。 不過,查詢提示仍必須接受。 數據表配對的聯結提示可能只會限制查詢提示中允許的聯結方法選取範圍。 如需詳細資訊,請參閱 聯結提示

DISABLE_OPTIMIZED_PLAN_FORCING

適用於:SQL Server (從 SQL Server 2022 (16.x) 開始)

停用 優化計劃強制查詢

強制執行最佳化計畫可減少重複強制查詢作業所額外產生的編譯負荷。 產生查詢執行計畫之後,系統會儲存特定的編譯步驟,以最佳化重新執行指令碼的形式重複使用。 最佳化重新執行指令碼會以隱藏 屬性的形式,儲存於OptimizationReplay的壓縮執行程序表 XML 之中。

展開檢視

指定已展開索引檢視表。 同時指定查詢優化器不會將任何索引檢視視為任何查詢元件的取代專案。 當檢視定義取代查詢文字中的檢視名稱時,就會展開檢視。

此查詢提示實際上不允許直接在查詢計劃中索引檢視表上使用索引檢視表和索引。

備註

如果查詢的 SELECT 元件中有檢視的直接參考,索引檢視會保持壓縮。 如果您指定 WITH (NOEXPAND)WITH (NOEXPAND, INDEX( <index_value> [ , *...n* ] ) ),檢視也會保持壓縮。 如需查詢提示 NOEXPAND的詳細資訊,請參閱使用 NOEXPAND

提示只會影響語句 SELECT 部分中的檢視,包括這些檢視在 INSERTUPDATEMERGEDELETE 語句中。

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 Database 開始。

已設定記憶體限制 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 Database 開始。

已設定記憶體限制 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組態選項 平行處理原則的最大程度。 也會覆寫指定此選項之查詢的資源管理員。 MAXDOP 查詢提示可能超過使用 sp_configure設定的值。 如果 MAXDOP 超過資源管理員設定的值,Database Engine 會使用 Resource Governor MAXDOP 值,如 ALTER WORKLOAD GROUP中所述。 當您使用 MAXDOP 查詢提示時,所有與 平行處理原則 組態選項搭配使用的所有語意規則都適用。 如需詳細資訊,請參閱 設定 max degree of parallelism 伺服器組態選項

警告

如果 MAXDOP 設定為零,則伺服器會選擇平行處理原則的最大程度。

MAXRECURSION <integer_value>

指定此查詢允許的遞歸數目上限。 數位 是介於 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 @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 Database Engine 為查詢產生新的暫存計劃,並在查詢完成執行之後立即捨棄該計劃。 當相同的查詢執行時,產生的查詢計劃不會取代儲存在快取中的計劃,而不需要 RECOMPILE 提示。 若未指定 RECOMPILE,Database Engine 會快取查詢計劃並重複使用它們。 編譯查詢計劃時,RECOMPILE 查詢提示會使用查詢中任何局部變數的目前值。 如果查詢位於預存程式內,則傳遞至任何參數的目前值。

RECOMPILE 是建立預存程序的實用替代方案。 RECOMPILE 只有在預存程式內的查詢子集而非整個預存程式時,才能使用 WITH RECOMPILE 子句。 如需詳細資訊,請參閱重新編譯預存程序。 當您建立計劃指南時,RECOMPILE 也很有用。

強固計劃

強制查詢優化器嘗試適用於最大可能數據列大小的計劃,可能犧牲效能。 處理查詢時,中繼數據表和運算符可能必須儲存和處理比處理查詢時任何一個輸入數據列更寬的數據列。 數據列可能非常寬,有時特定運算符無法處理數據列。 如果數據列很寬,Database Engine 會在查詢執行期間產生錯誤。 使用 ROBUST PLAN,您可以指示查詢優化器不要考慮任何可能遇到此問題的查詢計劃。

如果無法執行這類計劃,查詢優化器會傳回錯誤,而不是延遲錯誤偵測到查詢執行。 數據列可以包含可變長度的數據行;Database Engine 允許定義具有最大潛在大小的數據列,使其無法處理資料庫引擎。 一般而言,儘管可能的大小上限,但應用程式會儲存在 Database Engine 可以處理的限制內具有實際大小的數據列。 如果 Database Engine 遇到太長的數據列,則會傳回執行錯誤。

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' 在估計篩選條件的 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 Database
'ASSUME_PARTIAL_CORRELATION_FOR_FILTER_ESTIMATES' 在估計篩選條件的 AND 述詞以考慮部分相互關聯時,使用最多到最少的選擇性來產生計劃。 此提示名稱是 SQL Server 2014 (12.x) 和更新版本基數估計模型的預設行為。

適用於:Azure SQL Database
'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_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 Database
'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 和更新版本

1QUERY_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 與另一個查詢提示衝突,或查詢層級啟用的追蹤旗標(例如 QUERYTRACEON),SQL Server 會在嘗試執行查詢時產生錯誤。

USE PLAN N'xml_plan'

強制查詢優化器針對 xml_plan所指定的查詢使用現有的查詢計劃。 USE PLAN 無法使用 INSERTUPDATEMERGEDELETE 語句來指定。

這項功能所強制產生的執行計劃與強制執行計劃相同或類似。 由於產生的計劃可能與 USE PLAN所指定的計劃不同,因此計劃的效能可能會有所不同。 在罕見的情況下,效能差異可能是顯著和負面的;在此情況下,系統管理員必須移除強制計劃。

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

將指定的數據表提示套用至對應至 exposed_object_name的數據表或檢視表。 我們建議您只在 計劃指南的內容中,才將資料表提示當做查詢提示使用。

exposed_object_name 可以是下列其中一個參考:

  • 當別名用於查詢 FROM 子句中的數據表或檢視時,exposed_object_name 為別名。

  • 未使用別名時,exposed_object_nameFROM 子句中所參考之數據表或檢視表完全相符。 例如,如果使用兩部分名稱參考數據表或檢視表,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_valueindex_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 做為查詢提示之數據表或檢視表的數據表提示。 如需這些提示的描述,請參閱 資料表提示

除非查詢已經有指定數據表提示的 WITH 子句,否則不允許 INDEXFORCESCANFORCESEEK 以外的數據表提示作為查詢提示。 如需詳細資訊,請參閱<一节

謹慎

使用參數指定 FORCESEEK 會限制查詢優化器可考慮的計劃數目,而不是指定不含參數的 FORCESEEK 時。 這可能會導致在更多情況下發生「無法產生計劃」錯誤。

FOR TIMESTAMP AS OF 'point_in_time'

適用於:Microsoft網狀架構數據倉儲

使用 OPTION 子句中的 TIMESTAMP 語法來查詢數據,因為它存在於過去,這是 Microsoft Fabric 中 Synapse 數據倉儲中的一部分時間移動功能。

指定格式 point_in_timeyyyy-MM-ddTHH:mm:ss[.fff] 傳回當時出現的數據。 時區一律為UTC。 針對具有 樣式 126的必要日期時間格式,使用 CONVERT 語法。

TIMESTAMP AS OF 提示只能使用 OPTION 子句來指定一次。 如需詳細資訊和限制,請參閱 查詢數據,因為它存在於過去

FORCE [ 單一節點 |DISTRIBUTED ] PLAN

適用於:Microsoft網狀架構數據倉儲

允許使用者選擇是否強制單一節點計劃或分散式計劃來執行查詢。

備註

查詢提示無法在 INSERT 語句中指定,除非語句內使用 SELECT 子句。

查詢提示只能在最上層查詢中指定,而不是在子查詢中。 當數據表提示指定為查詢提示時,可以在最上層查詢或子查詢中指定提示。 不過,TABLE HINT 子句中針對 exposed_object_name 指定的值必須完全符合查詢或子查詢中公開的名稱。

將數據表提示指定為查詢提示

我們建議只在 計劃指南的內容中使用 INDEXFORCESCANFORCESEEK 數據表提示作為查詢提示。 例如,當您無法修改原始查詢時,計劃指南很有用,因為它是第三方應用程式。 在編譯並優化之前,計劃指南中指定的查詢提示會新增至查詢。 針對臨機作查詢,只有在測試計劃指南語句時,才使用 TABLE HINT 子句。 對於所有其他臨機作查詢,建議只將這些提示指定為數據表提示。

當指定查詢提示時,INDEXFORCESCANFORCESEEK 資料表提示對下列物件有效:

  • 資料表
  • 看法
  • 索引檢視
  • 通用資料表表示式(提示必須在結果集填入通用資料表表達式的 SELECT 語句中指定)
  • 動態管理檢視 (DMV)
  • 具名子查詢

您可以將 INDEXFORCESCANFORCESEEK 資料表提示指定為沒有任何現有資料表提示的查詢提示。 您也可以使用它們來分別取代查詢中的現有 INDEXFORCESCANFORCESEEK 提示。

除非查詢已經有指定數據表提示的 WITH 子句,否則不允許 INDEXFORCESCANFORCESEEK 以外的數據表提示作為查詢提示。 在此情況下,也必須將相符的提示指定為查詢提示。 使用 OPTION 子句中的 TABLE HINT,將比對提示指定為查詢提示。 此規格會保留查詢的語意。 例如,如果查詢包含數據表提示 NOLOCK,則計劃指南之 @hints 參數中的 OPTION 子句也必須包含 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網狀架構數據倉儲:

  • FORCE SINGLE NODE PLANFORCE DISTRIBUTED PLAN

範例

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

下列範例會指示查詢優化器針對 @city_name 使用值 'Seattle',並在優化查詢時,針對 @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 提示將遞歸層級的數目限制為兩個。 此範例會使用 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

下列範例使用數據表提示 FORCESEEKTABLE 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 提示。 您可以使用提示,而不指定提示來覆寫您在查詢 FROM 子句中指定的 INDEX 數據表提示行為。 此範例會使用 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 提示之外,指定 INDEXFORCESEEK 提示,並在語句編譯和優化期間取代查詢中對非語意影響 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 提示來選擇。 您可以指定提示,因為它會影響語意。 然後,只指定具有數據表參考且沒有 INDEX 提示的 TABLE HINT 關鍵詞。 此範例會使用 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 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,包括 RECOMPILEMAXDOP 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 中的倉儲

使用 OPTION 子句中的 TIMESTAMP 語法,在 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