發現那些未被使用的數據庫索引
為了確保快速訪問數據,和其他關系型數據庫系統一樣SQL Server 會利用索引來快速的查找數據,SQL Server可以創建諸如聚集索引、非聚集索引、XML索引和全文本索引的不同類型的索引。
有多個索引的好處是如果存在合適的索引,SQL Server可以快速存取數據,有太多索引的缺點是SQL Server不得不維護這些索引,維護也需要代價,并且索引也需要額外的存儲空間,所以,索引對性能來講是一把雙刃劍。
下來我們看看如何標識存在但沒有被使用到的索引,進而刪除他們,降低存儲需求。
我們知道SQL Server 2005增加了DMVs-動態管理視圖,允許你更深一步窺探在SQL Servr里發生了什么,其中一些是用來查看索引是怎么被使用的,我們討論兩個DMVs,注意這些視圖存儲累積的數據,所以SQL Server重置狀態時,計數器要歸0,所以當監視索引使用時要注意這些。
- DMV- sys.dm_db_index_operational_stats
這個DMV 允許您查看插入、 更新和刪除的索引的各個方面的信息,基本上它會顯示在用在基于數據的修改方面維護索引的很多工作。
如果你對表的查詢返回了所有列,輸出可能會令人困惑,所以我們把焦點集中到少許列上,想知道其他列的情況可以查看Online Books
- SELECT OBJECT_NAME(A.[OBJECT_ID]) AS [OBJECT NAME],
- I.[NAME] AS [INDEX NAME],
- A.LEAF_INSERT_COUNT,
- A.LEAF_UPDATE_COUNT,
- A.LEAF_DELETE_COUNT
- FROM SYS.DM_DB_INDEX_OPERATIONAL_STATS (db_id(),NULL,NULL,NULL ) A
- INNER JOIN SYS.INDEXES AS I
- ON I.[OBJECT_ID] = A.[OBJECT_ID]
- AND I.INDEX_ID = A.INDEX_ID
- WHERE OBJECTPROPERTY(A.[OBJECT_ID],’IsUserTable’) = 1
下面我們就看到inserts,updates,deletes發生在每一個索引上的數字,所以,這表明SQL Server花費許多工作不得不維護索引
- DMV – sys.dm_db_index_usage_stats
這個DMV顯示索引在用戶的查詢中使用了多少次,其他列請參閱聯機叢書。
- SELECT OBJECT_NAME(S.[OBJECT_ID]) AS [OBJECT NAME],
- I.[NAME] AS [INDEX NAME],
- USER_SEEKS,
- USER_SCANS,
- USER_LOOKUPS,
- USER_UPDATES
- FROM SYS.DM_DB_INDEX_USAGE_STATS AS S
- INNER JOIN SYS.INDEXES AS I ON I.[OBJECT_ID] = S.[OBJECT_ID] AND I.INDEX_ID = S.INDEX_ID
- WHERE OBJECTPROPERTY(S.[OBJECT_ID],’IsUserTable’) = 1
- AND S.database_id = DB_ID()
我們使用了seeks,scans,lookups和updates
- The seeks 搜索指的是在Index上發生了多少次Index Seek,seek是最快的訪問數據的方式。
- The scans 掃描指的是在index上發生了多少次index Scan,Scan 是從多行數據中查找你想要的數據,應盡量避免scan
- The lookups 查找是指查詢所需的數據有多少次是從Clustered index 或者是heap中進行的
- The updates 更新是指由于數據的更新導致index被更改了多少次
標識未使用的索引
基于以上的輸出結果我們把焦點定位到第二個查詢上,我們能看到這個索引沒有發生過seeks,scans和lookup,但是發生了updates,這意味著SQL Server在滿足查詢時沒有使用到這個index,但是仍然需要維護它,記住從DMVs獲得的這些數據當SQL Server重新啟動時要復位,為確定哪一個index應該保留還是刪除要確保你采集的是足夠長一段時間的數據。