查詢提示 (Transact-SQL)

更新: 2007 年 9 月 15 日

指定應該在整個查詢中使用指示的查詢提示。查詢提示會影響陳述式中的所有運算子。如果主要查詢涉及 UNION,只有最後一個包含 UNION 作業的查詢可以有 OPTION 子句。查詢提示指定在 OPTION 子句中。如果一或多個查詢提示造成查詢最佳化工具不會產生有效的計劃,就會產生 8622 錯誤。

ms181714.note(zh-tw,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-tw,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-tw,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 選項>。
  • OPTIMIZE FOR
    指示查詢最佳化工具在查詢進行編譯和最佳化時,使用特定的本機變數值。只有在查詢最佳化期間,才使用這個值,在查詢執行期間,不使用這個值。OPTIMIZE FOR 可以抵銷最佳化工具的參數偵測行為,當您建立計劃指南時,也可以使用它。如需詳細資訊,請參閱<重新編譯預存程序>和<使用計劃指南對已部署應用程式中的查詢進行最佳化>。
  • @variable_name
    這是查詢所用之本機變數的名稱,您可以指派這個本機變數的值來搭配使用 OPTIMIZE FOR 查詢提示。
  • literal_constant
    這是將指派給 @variable_name,以便搭配 OPTIMIZE FOR 查詢提示使用的常值常數值。只有在查詢最佳化期間,才使用 literal_constant,在查詢執行期間,不能用來做為 @variable_name 的值。literal_constant 可以是任何能夠用常值常數來表示的 SQL Server 系統資料類型。literal_constant 的資料類型必須可以隱含地轉換為 @variable_name 在查詢中參考的資料類型。
  • ,…n
    指出可以將某個 literal_constant 指派給多個 @variable_name,以便搭配 OPTIMIZE FOR 查詢提示來使用。
  • PARAMETERIZATION { SIMPLE | FORCED }
    指定 SQL Server 查詢最佳化工具在查詢完成時套用在查詢的參數化規則。

    ms181714.note(zh-tw,SQL.90).gif重要事項:
    PARAMETERIZATION 查詢提示只能指定在計劃指南內。您不能在查詢中直接指定它。

    SIMPLE 指示查詢最佳化工具嘗試簡單參數化。FORCED 指示最佳化工具嘗試強制參數化。PARAMETERIZATION 查詢提示用來覆寫計劃指南內 PARAMETERIZATION 資料庫 SET 選項目前的設定。如需詳細資訊,請參閱<使用計劃指南指定查詢參數化行為>。

  • RECOMPILE
    指示 SQL Server 2005 Database Engine 捨棄在執行查詢之後所產生的計劃,強制查詢最佳化工具在下次執行相同的查詢時,重新編譯查詢計劃。在未指定 RECOMPILE 的情況下,Database Engine 會快取查詢計劃和重複使用它們。當編譯查詢計劃時,RECOMPILE 查詢提示會使用查詢中任何本機變數目前的值,如果查詢在預存程序內,就會將目前的值傳給任何參數。

    當不必編譯整個預存程序,只需要重新編譯預存程序內的部分查詢時,RECOMPILE 是非常有用的替代方案,可供您建立使用 WITH RECOMPILE 子句的預存程序。如需詳細資訊,請參閱<重新編譯預存程序>。另外,當您建立計劃指南時,RECOMPILE 也非常有用。如需詳細資訊,請參閱<使用計劃指南對已部署應用程式中的查詢進行最佳化>。

  • ROBUST PLAN
    強制查詢最佳化工具嘗試一項適用於最大潛在資料列大小的計劃,可能會犧牲效能。當處理查詢時,中繼資料表和運算子可能需要儲存和處理比任何輸入資料列還寬的資料列。這些資料列的寬度,有時會使特定運算子無法處理資料列。如果發生這個情況,在查詢執行期間,Database Engine 會產生一則錯誤。您可以利用 ROBUST PLAN 來指示查詢最佳化工具,不考慮任何可能發生這個問題的查詢計劃。

    如果不可能執行這類計劃,查詢最佳化工具會傳回錯誤,而不是將錯誤偵測延遲到查詢執行時。資料列可能包含可變長度的資料行;Database Engine 允許資料列定義成超出 Database Engine 處理能力的最大潛在大小。一般而言,雖然有最大潛在大小,但應用程式仍會儲存實際大小在 Database Engine 處理能力限制之內的資料列。如果 Database Engine 發現太長的資料列,便會傳回執行錯誤。

  • 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 陳述式之 SELECT 部分中的檢視表。

  • MAXRECURSION number
    指定這項查詢所能擁有的最大遞迴數目。number 是 0 和 32767 之間的非負整數。當指定 0 時,不會套用任何限制。如果未指定這個選項,伺服器的預設限制是 100。

    在查詢執行期間,當到達 MAXRECURSION 限制的指定或預設數目時,查詢會結束,且會傳回錯誤。

    陳述式的所有效果都會因這個錯誤而回復。如果陳述式是 SELECT 陳述式,可能會傳回部分結果,或根本不傳回任何結果。任何傳回的部分結果都不會包括超出指定的最大遞迴層級之遞迴層級的所有資料列。

    如需詳細資訊,請參閱<WITH common_table_expression (Transact-SQL)>。

  • USE PLAN N**'xml_plan'**
    強制查詢最佳化工具將現有的查詢計劃用在 'xml_plan' 所指定的查詢上。如需詳細資訊,請參閱<以強制執行計劃來指定查詢計劃>。USE PLAN 無法搭配 INSERT、UPDATE 或 DELETE 陳述式一起使用。

備註

除非是在陳述式內使用 SELECT 子句,否則,無法在 INSERT 陳述式中指定查詢提示。

您只能在最上層查詢中指定查詢提示,不能在子查詢中指定查詢提示。

範例

A. 使用 MERGE JOIN

下列範例指定由 MERGE JOIN 來執行查詢中的 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 提示,將遞迴層級限制為 2。

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 的範例。