1. 程式人生 > >sql查詢效能除錯,用SET STATISTICS IO和SET STATISTICS TIME---解釋比較詳細

sql查詢效能除錯,用SET STATISTICS IO和SET STATISTICS TIME---解釋比較詳細

    如果調節查詢效能的目的是讓它使用盡可能少的伺服器資源,而不是查詢執行的時間最短,那麼就更容易測試你採取的措施是提高了查詢的效能還是降低了查詢的效能。尤其是在資源利用不斷變化的伺服器上更是如此。首先,需要搞清楚在對查詢進行調節時,如何測試我們的伺服器的資源使用情況。
    在開始我們的例子前,先執行下面的這二條命令(不要在正在使用的伺服器上執行),這二條命令將清除SQL Server的資料和過程緩衝區,這樣能夠使我們在每次執行查詢時在同一個起點上,否則,每次執行查詢得到的結果就不具有可比性了:
DBCC DROPCLEANBUFFERSDBCC FREEPROCCACHE
輸入並執行下面的Transact-SQL命令:
SET STATISTICS IO ON  
SET STATISTICS TIME ON

一旦上面的準備工作完成後,執行下面的查詢:
SELECT * FROM [order details]
顯示結果:
SQL Server parse and compile time: (SQL Server解析和編譯時間:)
CPU time = 10 ms, elapsed time = 61 ms. ……
(1)

SQL Server parse and compile time: (SQL Server解析和編譯時間:)
CPU time = 0 ms, elapsed time = 0 ms. ……(2)

(所影響的行數為 2155 行) ……(3)

Table 'Order Details'. Scan count 1, logical reads 10, physical reads 1, read-ahead reads 9.
(表:Order Details,掃描計數1,邏輯讀取10 次,物理讀取1 次,預讀9次) ……(4)

SQL Server Execution Times:
(SQL Server執行時間:)
CPU time = 30 ms, elapsed time = 387 ms. ……(5)

標誌(1)表示SQL Server解析“ELECT * FROM [order details]”命令並將解析的結果放到SQL Server的過程緩衝區中供SQL Server使用所需要的CPU執行時間和總的時間。
標誌(2)表示SQL Server從過程緩衝區中取出解析結果供執行的時間,大多數情況下這二個值都會是0,因為這個過程執行得相當地快
標誌(5)表示執行這次查詢使用了多少CPU執行時間和執行查詢使用了多少時間。CPU執行時間是對執行查詢所需要的CPU資源的一種相對穩定的測量方法,與CPU的忙閒程度沒有關係。但是,每次執行查詢時這一數字也會有所不同,只是變化的範圍沒有總時間變化大。總時間是對查詢執行所需要的時間(不計算阻塞或讀資料的時間),由於伺服器上的負載是在不斷變化的,因此這一資料的變化範圍有時會相當地大。

(由於CPU佔用時間是相對穩定的,因此可以使用這一資料作為衡量你的調節措施是提高了查詢效能還是降低了查詢的效能的一種方法。)
標誌(4)是SET STATISTICS IO的效果

Scan Count:在查詢中涉及到的表被訪問的次數。在我們的例子中,其中的表只被訪問了1次,由於查詢中不包括連線命令,這一資訊並不是十分有用,但如果查詢中包含有一個或多個連線,則這一資訊是十分有用的。(一個迴圈外部的表的Scan Count值為1,但對於一個迴圈內的表而言,其值為迴圈的次數。可以想象得到,對於一個迴圈內的表而言,其ScanCount值越小,它所使用的資源越少,查詢的效能也就越高。因此在調節一個帶連線的查詢的效能時,需要關注Scan Count的值,在進行調節時,注意觀察它是增加還是減少了。)
Logical Reads: 這是SET STATISTICS IO或SET STATISTICS TIME命令提供的最有用的資料。我們知道,SQL Server在可以對任何資料進行操作前,必須首先把資料讀取到其資料緩衝區中。此外,我們也知道SQL Server何時會從資料緩衝區中讀取資料,並把資料讀取到大小為8K位元組的頁中。那麼LogicalReads的意義是什麼呢?Logical Reads是指SQL Server為得到查詢中的結果而必須從資料緩衝區讀取的頁數。在執行查詢時,SQL Server不會讀取比實際需求多或少的資料,因此,當在相同的資料集上執行同一個查詢,得到的LogicalReads的數字總是相同的。(SQL Server執行查詢時的Logical Reads值每一次這個數值是不會變化的。因此,在進行查詢效能的調節時,這是一個可以用來衡量你的調節措施是否成功的一個很好的標準。如果Logical Reads值下降,就表明查詢使用的伺服器資源減少,查詢的效能有所提高。如果Logical Reads值增加,則表示調節措施降低了查詢的效能。在其他條件不變的情況下,一個查詢使用的邏輯讀越少,其效率就越高,查詢的速度就越快。)
Physical Reads:物理讀,在執行真正的查詢操作前,SQL Server必須從磁碟上向資料緩衝區中讀取它所需要的資料。在SQL Server開始執行查詢前,它要作的第一件事就是檢查它所需要的資料是否在資料緩衝區中,如果在,就從中讀取,如果不在,SQLServer必須首先將它需要的資料從磁碟上讀到資料緩衝區中。我們可以想象得到,SQL Server在執行物理讀時比執行邏輯讀需要更多的伺服器資源。因此,在理想情況下,我們應當儘量避免物理讀操作。下面的這一部分聽起來讓人容易感到糊塗了。在對查詢的效能進行調節時,可以忽略物理讀而只專注於邏輯讀。你一定會納悶兒,剛才不是還說物理讀比邏輯讀需要更多的伺服器資源嗎?情況確實是這樣, SQLServer在執行查詢時所需要的物理讀次數不可能通過效能調節而減少的。減少物理讀的次數是DBA的一項重要工作,但它涉及到整個伺服器效能的調節,而不僅僅是查詢效能的調節。在進行查詢效能調節時,我們不能控制資料緩衝區的大小或伺服器的忙碌程度以及完成查詢所需要的資料是在資料緩衝區中還是在磁碟上,唯一我們能夠控制的資料是得到查詢結果所需要執行的邏輯讀的次數。因此,在查詢效能的調節中,我們可以心安理得地不理會SET STATISTICS IO命令提供的PhysicalRead的值。(減少物理讀次數、加快SQL Server執行速度的一種方式是確保伺服器的實體記憶體足夠多。)

Read-Ahead Reads: 與Physical Reads一樣,這個值在查詢效能調節中也沒有什麼用。Read-Ahead Reads表示SQL Server在執行預讀機制時讀取的物理頁。為了優化其效能,SQL Server在認為它需要資料之前預先讀取一部分資料,根據SQLServer對資料需求預測的準確程度,預讀的資料頁可能有用,也可能沒用。在本例中,Read-Ahead Reads的值為9,Physical Read的值為1,而LogicalReads的值為10,它們之間存在著簡單的相加關係。
        
          那麼我在伺服器上執行查詢時的過程是怎麼樣的呢?首先,SQL Server會開始檢查完成查詢所需要的資料是否在資料緩衝區中,它會很快地發現這些資料不在資料緩衝區中,並啟動預讀機制將它所需要的10個數據頁中的前9個讀取到資料緩衝區。當SQL Server檢查是否所需要的全部資料都已經在資料緩衝區時,會發現已經有9個數據頁在資料緩衝區中,還有一個不在,它就會立即再次讀取磁碟,將所需要的頁讀到資料緩衝區。一旦所有的資料都在資料緩衝區後,SQLServer就可以處理查詢了。

總結:在對查詢的效能進行調節時用一些科學的標準來測量你的調節措施是否有效是十分重要的。問題是,SQL Servers的負載是動態變化的,使用查詢總的執行時間來衡量你正在調節效能的查詢的效能是提高了還是沒有,並不是一個合理的方法。
更好的方法是比較多個數據,例如邏輯讀的次數或者查詢所使用的CPU時間。因此在對查詢的效能進行調節時,需要首先使用SET STATISTICS IO和SET STATISTICS TIME命令向你提供一些必要的資料,以便確定你對查詢效能進行調節的措施是否真正地得到了目的。

======================
1.測試前用二條命令清除SQL Server的資料和過程緩衝區,以保證測試條件相同:
DBCC DROPCLEANBUFFERS和DBCC FREEPROCCACHE
2.SET STATISTICS TIME:看cpu時間   
3.SET STATISTICS IO:關注scan count(計數)------查詢讀取的表數量;logical read( 邏輯讀)次數
======================

PS:經測試確認SqlServer 2005中對錶的連線條件會自動進行優化,但為了養成良好的習慣和在其他資料庫上開發的效能考慮,需繼續保持大表連線欄位放在左邊的習慣