快速找出數據庫的性能問題之:缺失索引 &無用的索引


 

       我們通過減少查詢中的不必要的讀取操作從而使得查詢的性能得到提升。一個查詢在數據庫中執行的讀操作越多,那么就對磁盤,CPU,內存的壓力越大。除非整個數據庫的數據全在在內存中,否則每次的讀操作都會把數據從磁盤讀入到內存中,然后返回。

       一個查詢在讀取一個資源的時候,通過加鎖會阻止其他的查詢對這個資源進行修改,此時其他要操作這個資源的查詢就需要等待,從而導致了延時。

 

       誠然,有些等待是必須的,讀取操作也是必須的,但是一些因為我們代碼或者設計導致的過度的讀取操作和等待,那就會嚴重影響性能,尤其是當數據庫的訪問量開始變大的時候。

可以說在SQL Server中,最高效的讀取數據方式就是通過索引去獲取數據。如果在數據表中存在缺失索引的問題,結果可想而知。

在本篇中,我們將會討論下面幾個議題:

    1. 如何識別缺失索引性能問題
    2. 識別沒有用的索引
    3. 如何解決上面的問題

 

確實本篇講述的內容涉及到了一些與數據庫性能調優的話題,對於調優而言,難點很多時候在於如何正確的找出性能問題。

下面,我們首先來看看缺失索引。

 

缺失索引

 

       SQL Server可以在表字段上面建立索引,從而使得Where和Join這樣的語句執行的更快。當查詢優化器在優化一個查詢的時候,它會保存一些來暗示哪些列上可能建立索引之后可能性能會更快的信息。我們可以通過動態管理視圖sys.dm_db_missing_index_details來查看,運行如下查詢

 20120410222906.png

查詢的結果如下:

 

20120410223001.png

下面,我們就來稍微的解釋一下結果中主要字段的含義:

字段名字

說明

DatabaseName

告訴我們是哪一個數據庫上面存在缺失索引的問題

equality_columns

如果在某個字段上面進行了相等的操作,例如Name=’Agilesharp’,在Name字段上面進行了判等的操作,如果查詢優化器認為這個Name上面缺失索引,那么這個Name就會出現在上述查詢的結果中。

多個字段,用逗號分割

inquality_columns

在某個字段上進行了不等的操作,例如ID>1等,如果ID上面存在缺失索引,那么ID就會出現在這里

Included_columns

告訴我們那些數據列可以作為索引包含列放在索引中,從而減少書簽查找的開銷

Statement

告訴哪一個表上面存在缺失索引的問題

 

       當然,上面的DMV查詢所得到的結果只是推薦結果,至於是否要去在相應的列上面建立索引,還需要進行綜合的分析,不能單靠一方面來判斷,例如,我們可以在去制定一些計划去運行SQL Profiler去跟蹤數據庫,然后分析跟蹤的數據,並且分析這個列的數據的分布情況,分析數據的密度和差異性,而且還可以進一步的分析列的統計信息,然后決定是否要加索引。

 

       注:我也正在寫SQL Server Profiler的文章,還沒有發布,請大家耐心等待。另外SQL Server的調優是個非常深的話題,大家可以通過我這里的一些問題在掌握一些所謂的小技巧,起到一個拋磚引玉的作用!

 

       說了這么多,可能大家感覺像是沒有說,感覺有點虛。確實,我也感覺這樣,因為就這分析缺失索引的問題要考慮的問題就N多。agilesharp的其他系列文章也在討論SQL Server的性能問題,這里,我們就不多說,也不把問題搞復雜了。我再送朋友一段分析的代碼,可以更好的幫助我們找到缺失索引的問題:

 

20120410223105.png

上面的查詢比較不錯,按照成本進行了分析,成本越大,就說明加了索引之后,收益就越大,可以看到如下的結果:

 

20120410223202.png

 

然后大家加了索引之后,可以多多的測試,可以查看執行計划,也可以查看查詢的數據頁的讀取情況,I/O的情況:

20120410223243.png

 

沒有用的索引

 

       正如在上一小節所的講的,創建一個索引是一個非常需要重視的問題,需要考慮很多的方面,因為,如果我們建立的索引沒有發揮作用,甚至說,查詢優化器不采用我們的索引,那么就會帶來適得其反的效果。

 

       索引的維護是需要成本,甚至使得數據庫的性能變得很低,特別實在數據更新的時候。當在數據表上面進行數據的更新,刪除,和插入的時候,都會導致索引頁發生重新的調整,導致索引頁中的數據重新的排序,從而導致數據表被鎖定。

          

所以,我們很有必要找出沒有發揮作用的索引,我們還是可以采用DMV來快速的查看:

201204101000.png

        這里不否認,要完全明白上面的查詢的意思卻不是一件容易的事情,大家可以暫時不用懂,可以把這些腳本保存起來,作為一個小的工具使用。

查詢結果如下:

20120410223532.png

 

       因為我這里采用的是一個示例數據庫,所以看到的結果不是很多,但是可以發現:這些索引一些在被不斷的更新(user_updates),但是沒有被用過(system usage)。

 

對無用索引的解決很簡單:刪除索引就OK了。

 

關於腳本,請大家在附件中下載,可以保留起來,並且大家還可以修改,查詢指定的數據庫的情況。

 

附件:scripts.zip

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM