SQL Server 如何比對計畫指南與查詢

SQL Server 會比對類型 OBJECT 的計畫指南與查詢,而此查詢會出現在 sp_create_plan_guide 預存程序的 @module_or_batch 引數指定的預存程序、觸動程序或函數 (模組) 內。如果模組上有計畫指南存在,就會將計畫指南與指定的查詢相比對。

對於批次內提交的查詢,SQL Server 會先嘗試比對該查詢跟 SQL 型的計畫指南,接下來嘗試將查詢參數化,然後再比對一次,以此來比對計畫指南跟查詢。下圖提供此程序的概觀。

SQL Server 如何將計畫指南與查詢相符

  1. SQL Server 查詢最佳化工具會將執行的批次辨識為要求,以在批次內編譯每個陳述式。

  2. 對於批次內的特定陳述式,SQL Server 會嘗試比對陳述式與 SQL 型計畫指南,而該指南的 @module_or_batch 引數會與內送的批次文字相符,包括任何常數常值在內;而且其 @stmt 引數也會跟批次中的陳述式相符。如果有這類計畫指南而且比對完全相符,則就會修改陳述式文字以包含計畫指南中指定的查詢提示。接著會據以編譯陳述式。

  3. 如果計畫指南跟步驟 2 的陳述式不相符,那麼 SQL Server 會嘗試使用強制參數化,以參數化該陳述式。在此步驟中,以下任何一個原因都會使參數化失敗:

    1. 該陳述式已經完成參數化,或是包含本機變數。

    2. 套用了 PARAMETERIZATION SIMPLE 資料庫 SET 選項 (預設值),而且套用至陳述式同時指定 PARAMETERIZATION FORCED 查詢提示的類型 TEMPLATE 沒有計畫指南。

    3. 套用到陳述式同時指定 PARAMETERIZATION SIMPLE 查詢提示的類型 TEMPLATE 有計畫指南。

    如果順利強制參數化,SQL Server 會嘗試比對陳述式的參數化表單與類型 SQL 的計畫指南,而此指南是以該參數化陳述式建立。如果有這類計畫指南而且比對完全相符,則就會修改陳述式文字以包含計畫指南中指定的查詢提示。接著會據以編譯陳述式。如果沒有相符的計畫指南,參數化陳述式就會進行編譯,而不會由計畫指南進行修改。

  4. 如果在步驟 3 進行參數化失敗,SQL Server 就會再次嘗試將陳述式參數化。SQL Server 這一次會套用預設的簡單參數化行為。然後就會直接編譯結果查詢。計畫指南不會與簡單參數化的結果相符。

    [!附註]

    類型 SQL 的計畫指南中會忽略 RECOMPILE 查詢提示,而此計畫指南套用了透過強制或簡單參數化而參數化的查詢。同時會發出警告。