2011年6月6日 星期一

你是否需要 SQL Server Query Hint ?

下列的文章是從SQL Server Magazine轉載而來的,因為覺得本篇非常有參考價值,所以特別轉載於此,再請大家參考。

SQL Server 在之前的版本中一直有支援 Query Hints的功能,但在數量上真的是用一支手就可以數的出來,現在,你可以觀看SQL Server的參考文件,數量之多已經無法列在一個頁面中,也可以參考網站Hints的頁面看到三種不同Hints的資訊。

Hints (Transact-SQL):http://msdn.microsoft.com/en-us/library/ms187713.aspx

什麼是hint?在英文上 hint代表著一個溫和的建議,但在SQL Server中hint是一個指令告訴SQL Server中的 (optimizer) 進行最佳化與查詢計畫中如何進行,除非hint是不能實作的。在事實上,很多人認為使用hints會影響一個查詢的計畫。

(optimizer) 是一個SQL Server 引擎中的元件,負責決定查詢如何的進行與處理。他決定 indexes 將如何使用,與表格中如何排序處理和合併 (join) 表格時該如何的執行,查詢將是否執行在不同的處理單元中,也可能是整個引擎中最複雜的部份。在先前的SQL Server的版本中,設計 (optimizer) 的工程師想到有一天他們將有一個 (optimizer) 總是可以進行最佳的方案,所以每個查詢就不再需要再額外的撰寫 query hints。事實上在SQL Server 7之前,作者使用hint去改善 (optimizer) 的執行計畫,而  (optimizer)  的工程師也試著去理解這些情況,並嘗試理解為什麼 (optimizer) 在沒有使用hints的情況下,無法產生出更好查詢計畫。

有一段期間中 hints 讓 (optimizer) 變的越來越複雜,但是相對的,真實上也發生了。讓更多的特色增加到SQL Server中,也讓查詢變得越來越複雜在大型的資料數據上,(optimizer)  現在會這麼複雜,這麼多可能的執行計劃,研究上沒有辦法總是設計出最佳的方案。在目標上將討論如何讓執行計劃更好,不需更多的時間去進行查詢。在2010的會議上,Microsoft's David DeWitt有談到一個主題為 "SQL Query 優化為什麼他這麼難正確" 描述為什麼 (optimizer) 這麼的複雜。(詳細內容可以參考 www.sqlpass.org/summit/na2010/LiveKeynotes/Thursday.aspx) 當各個SQL Server的版本增加越來越多的 hints時,支援性的事實 (optimizer)總是不能提供最好的執行計畫,文件頁面參考在作者最先章節仍然包含下列的警告:

警告:
因為SQL Server 查詢的 (optimizer) 代表著一個查詢的最佳執行計畫,我建議可以透過 <join_hint>, <query_hint>, 和 <table_hint> 作為最後的手段如同一個經驗豐富的開發人員或資料庫管理者。

如同作者之前提及,hints 分成三個種類,如你看到的警告示語中,稱為 join hints、query hints和 table hints,作者實際上呼叫第二種稱為 "option hints" 因為他們特別在一個選項在你的查詢結束。(作者認為全部的hints可以認為是 query hints.)

我們顯然沒有足夠的空間用於討論任何類型的hints 技術,但是在此將給予你一個技術上小秘密,join hint 是注重在 LOOP join 和 OPTION hint。稱為 LOOP JOIN,讓我們來看看有那些不同。Join hint是指定在join的子句中 (如同你必須在使用結合時指定使用join的關鍵字)。當你使用一個 join hint。他應用在兩個表格進行結合。而使用 LOOP JOIN 如同一個 option hint,他可以應用在全部的join查詢中。你可能想在兩個表格結合時,或許不需要使用join hint or option hint,但是再想想,如果你使用一個join hint,他有一邊會影響表格合併時的排序,在下面最先的查詢中,額外去使用 LOOP JOIN的 (optimizer)將製造確認SalesOrderHeader在執行時是最先的表格存取,反之在第二個查詢中,(optimizer)能夠決定他們自已那一個進行先存取。


SELECT *
FROM sales.SalesOrderheader h INNER LOOP JOIN sales.SalesOrderDetail d
ON h.SalesOrderID = d.SalesOrderDetailID

SELECT *
FROM sales.SalesOrderheader h JOIN sales.SalesOrderDetail d
ON h.SalesOrderID = d.SalesOrderDetailID
OPTION (LOOP JOIN)


再次記住在心中,使用一個hint在你的程式碼中,這麼將減少SQL Server (optimizer) 的價值。如果 Service Pack 有更新 (optimizer),你可能會更不知道。更遭的是,如果你的資料中有經過 hints 更換過執行計畫,你有可能會得到最差的效能比你沒有使用hint的時候。

Hints還是有一點重要性,然而,這個重要性可能不是在你的查詢調整技術中的最高優先順序,還可能是最不重要的。hints是一個解決方案,當你沒有能夠找到其他的方法進行 SQL Server 的(optimizer)最佳化。但是取得一個 hint 從我和學習全部你能關於調整和最佳化之前你啟動大量地查詢透過你的程式碼。但是,使用 hints 從作者和你可以學習所有有關調整和優化,再開始使用在你的代碼中使用query hints。

相關文章:

  1. SQL Server 效能調整 - Optimizer Hint 的使用


參考連結:http://www.sqlmag.com/article/quering/do-you-need-a-sql-server-query-hint-

關鍵字:SQL Server Query HintHintsPerformance TuningOptimizer

沒有留言:

張貼留言