2011年6月9日 星期四

如何解讀 SQL Server 的圖型式執行計畫

本篇主要是從MSSQL Tips的網站轉載而來,主要介紹如何解讀一個圖型式的執行計畫,另外在圖示的部份,我另外從 Microsoft SQL Server 的網站中整理出來,我想解讀執行計畫應該是每一個 DBA 所需要具備的能力,所以特別在此介紹給大家。

問題:
在先前的章節中,作者有提到如何簡單的了解一個圖型化介面的查詢計畫。我們有機會深度的了解圖型式執行計畫的資訊來源。是的,你看的沒錯。但仍有其他的訊息,並無法直覺化的看出,需要進一步的解讀,如工具上的提示和屬性視窗的說明等。

方法:
在過去兩年間,作者不斷的提出與微軟產品相關的文章。意思上微軟作為一個軟件開發公司花了很多時間確保他們的產品也有類似的圖形用戶界面(GUI)設計和行為可以提供給使用者方便使用。

經常使用Microsoft產品的使用者,應該都知道無論是使用ExcelSQL Server Management Studio 其操作介面都會大致相同,都可以透過滑鼠右鍵進行進一步的資訊選擇。或是透過滑鼠移動到圖表上時,也是相同可以秀出額外的資訊。

類似其他的微軟產品,SQL Server Management Studio 也同樣有工具上的提示。圖型化查詢計畫將讓他提升到一個不同的等級,透過豐富的工具提示讓你看得更多。

記得最先的查詢和圖型式的執行計畫,作者已有表達在先前的作品集中?如果沒有,當下再我們再來看一次。作者繼續去使用他如同我們之前討論的基礎。這是一個非常簡單的 SELECT 語法在SQL Server 2005 - Northwind 的樣本資料庫之中,語法中包含一個過濾與排序操作。


SELECT [CustomerID], [CompanyName], [City], [Region]
FROM [Northwind].[dbo].[Customers]
WHERE [Country] = 'Germany'
ORDER BY [CompanyName]




在上面評估的執行計畫中,作者透過1到5的數字去幫助進行下面的解譯。

接著來看各個操作步驟的提示在這個簡單的執行計畫中,在閱讀方法上執行計畫本身從左到右進行參考。你將看到相似的操作提示,但是你應該注意到當你將箭頭移動到資料流與操作之間時,都會秀出提示讓你了解的更深入。

所以,如果你在各個項目的執行計劃中,你將取得不同的資訊,下列將秀出各自五個編號的資訊集合在這個執行計劃中。


1 - Clustered Index Scan Operator




作者將花一些時間去檢示每一個項目來說明,到目前為止我們已經看到第一個提示的部份,在此作者將只關注新的或不同的線性項目在每一個操作中的子項目提示。你會看到提示顯示的部份以及最初的操作標準化描述。接著經由評估操作程序 (在這個執行計畫的評估中)。如果這是一個真實的執行計畫,你會看到的實際數目也行參與的運作後的物理和邏輯運算的操作指標。

  • Physical Operation - 所用的實體運算子,如「雜湊聯結」或「巢狀迴圈」。實體運算子若以紅色顯示,表示查詢最佳化工具已發出警告,如遺漏資料行統計資料,或遺漏聯結述詞。這可能導致查詢最佳化工具出人意外地選擇效能低的查詢執行計畫。如需有關資料行統計資料的詳細資訊,請參閱<使用統計資料來改善查詢效能>。
    當圖形執行計畫建議建立或更新統計資料或建立索引時,就可以使用 SQL Server Management Studio 之 [物件總管] 的捷徑功能表,立即建立或更新遺漏的資料行統計資料與索引。如需詳細資訊,請參閱<索引的如何主題>。
  • Logical Operation - 符合實體運算子的邏輯運算子,如「內部聯結」運算子。邏輯運算子會列在位於在「工具提示」頂端的實體運算子後面。
  • Estimated I/O Cost - 這個值用來評估I/O操作的密集度。
  • Estimated CPU Cost - 該作業之所有 CPU 活動的估計成本。
  • Estimated Operator Cost - 查詢最佳化工具執行此作業的查詢成本。此作業的成本會當作查詢總成本的百分比顯示在括號內。因為查詢引擎會選擇最有效率的作業來執行查詢或執行陳述式,所以這個值應該越低越好。
  • Estimated Subtree Cost - 查詢最佳化工具執行此作業與同一子樹中此作業前面之所有作業的總成本。
  • Estimated Number of Rows - 由運算子產生的資料列數目。
  • Estimated Row Size - 由運算子產生的估計資料列大小 (位元組)。
  • Ordered - 一個布林值,用來指定運算子是否有將每一列進行排序。
  • NodeID - 查詢的執行計畫中具體的序號值。
接著在下半部的部份,分別另外有三個欄位的運算元分別為Predicate、Object 和 Output 。
  1. Predicate是一個術語,用來描述查詢中的過濾、描述或比較資料。在這個案例中,主要顯示查詢篩選結果,其中國家別的部份只顯示有興趣的國家別為 'Germany' 的資料行。
  2. Object用來描述這個執行計畫中Customers 的表格使用那一個主鍵值。
  3. Output主要顯示此次的語法中,會顯示那些欄位。


2- 資料流箭頭: Clustered Index Scan Operator to Sort Operator



你能分辯的出目前顯示出的是實際或估計的圖形式執行計劃嗎?他可能不是如你預期的這麼簡單。在圖型執行計畫中有兩種類型可以提示看出。無論如何,真實的查詢計畫將包含在Actual Number of Rows之中。


工具提示相關的數據流箭頭很簡單,他提供資訊去評估(或是真實的)資料移動在查詢的運算子之中。


3 -Sort Operator


在Sort operator 和 Clustered Index Scan operator在補捉的工具提示是相同的。顯然地,這些的值是不同的。你將可以看到評估子樹的成本增加與前面的操作。



4 - Data Flow Arrow: Sort Operator to SELECT Operator


我們在下一個遇到的資料流箭頭之間的排序和SELECT操作仍可能會有相同的內容(但並不一定有相同的值)。而且是幾乎同時的完成!



5- SELECT Operator



注意,在SELECT Operator's 的提示是大大不同於其他項目的提示如我們所見 - 在DML中將同樣有不同的比較到其他的操作項目,我們可以到 SELECT operator's 的操作方式。當然也可以看到其他的DML操作提示在這個項目中進行討論。在這個案例中,SELECT operator's 有一個新的項目為 Cached plan size。這個項目主要是指查詢計畫花了多少的cache進行處理。這個數值將可幫助你去了解 memorycache 的效能表現。

Microsoft SQL Server 的圖型式執行計畫提供了許多的資訊可以讓你了解到其中的操作方式,當然在此工具上也有一些無法直覺式看出的資訊,然而在本篇中也有介紹到如何進行觀察,而這此資訊也提供給我們在撰寫T-SQL時進行最佳化的調整,藉以讓執行計畫更有效率。



補充說明:圖型執行計畫圖示說明

下列圖示顯示在圖形執行計畫中,代表 SQL Server 用來執行陳述式的<資料指標邏輯與實體 Showplan 運算子>。
下列圖示顯示在圖形執行計畫中,代表 SQL Server 用來執行陳述式的Parallelism Showplan 運算子實體運算子。
圖示平行處理原則實體運算子
Distribute streams parallelism operator icon散發資料流
Repartition streams parallelism operator icon重新分割資料流
Gather streams parallelism operator icon收集資料流
下列圖示顯示在圖形執行計畫中,代表 SQL Server 使用的 Transact-SQL 語言項目。


參考網址:

  1. http://www.mssqltips.com/tip.asp?tip=1873
  2. http://msdn.microsoft.com/en-us/library/ms178071.aspx
  3. http://msdn.microsoft.com/zh-tw/library/ms175913.aspx

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