由於有了很多新功能,我們可以看到在SQL Server 2005和現在有SQL Server 2008中,Microsoft引進了一些動態管理視圖來協助確認基於查詢歷史的可能索引候選人。
這些動態管理視圖是:
n sys.dm_db_missing_index_details –返回關於缺失索引的詳細信息。
n sys.dm_db_missing_index_group_stats - 返回缺失索引組的摘要信息
n sys.dm_db_missing_index_groups – 返回一個具體組的缺失索引的信息。
n sys.dm_db_missing_index_columns(index_handle) – 返回在一個索引中缺失的數據庫表列的信息。這是一個函數,它要求傳遞index_handle。
和大多數動態管理視圖的跟蹤統計數據一樣,當SQL Server實例重啟,這些數據被完全清除時,這些工作方式基本上是一樣的。所以如果你在一個測試環境中工作並且重啟你的SQL Server實例,那麼這些視圖有可能不返回數據。
為了啟動,我們將使用一個從SQL Server 2005聯機幫助中得到的實例,這要求從AdventureWorks數據庫中查詢一張表而在StateProvinceID上沒有索引,如下所示:
USE AdventureWorks;
GO
SELECT City, StateProvinceID, PostalCode
FROM Person.Address
WHERE StateProvinceID = 1;
GO
一旦我們運行了上面的查詢,數據在動態管理視圖中應該可用。讓我們來快速看下每一個查詢。
第一個查詢從sys.dm_db_missing_index_details視圖中獲取數據。這可能是最有用的一個查詢,因為這給我們展示了object_id、equality_columns 和inequality_columns。另外,我們可以得到關於所含列的其它具體信息。
SELECT * FROM sys.dm_db_missing_index_details
圖一
所以從上面我們執行的查詢中,我們可以看到下面的信息:
n equality_columns = "StateProvinceID",這是因為這個字段和一個相等運算符在WHERE從句中使用。所以SQL Server告訴我們這將是針對索引的很好的選擇。
n inequality_columns = "NULL",如果你使用其它的運算符比如不相等,那麼這個字段將會有數據,但是由於我們使用等號,因此沒有一個字段將在這裡使用。
n included_columns =這是當創建一個索引時使用的其它字段。由於這個查詢只使用City、StateProvinceID 和 PostalCode,因此StateProvinceID將在索引中得到處理,當該索引創建時,其它兩個字段可能被用作內嵌的字段。
下一個索引從sys.dm_db_misssing_index_details中獲取數據。這個查詢使我們更了解其他統計數據,例如編譯,用戶查找,用戶掃描等,所以從這裡我們可以知道這個查詢多久會被訪問。如果我們創建一個基於這些信息的新索引,這將幫助我們確定多久使用一個索引可以獲得數據。
SELECT * FROM sys.dm_db_missing_index_details
由於這個查詢我們只執行了一次,因此我們的unique_compiles = 1 ,我們的 user_seeks = 1。如果我們再次運行這個查詢,我們的user_seeks應該會增加。
圖二
下一個視圖sys.dm_db_missing_index_groups將會給我們提供index_group_handle 和 index_handle的信息。
SELECT * FROM sys.dm_db_missing_index_groups
圖三
從上面查詢得到的結果基本上將用於從sys.dm_db_missing_index_columns函數中獲得數據。index_handle值被傳遞到下一個查詢,如下圖所示。
SELECT * FROM sys.dm_db_missing_index_columns(1)
圖四
要得到在一個結果集顯示的所有數據,下面從SQL Server 2005聯機幫助中得到的查詢將為我們提供這些數據。
SELECT mig.*, statement AS table_name,
column_id, column_name, column_usage
FROM sys.dm_db_missing_index_details AS mid
CROSS APPLY sys.dm_db_missing_index_columns (mid.index_handle)
INNER JOIN sys.dm_db_missing_index_groups AS mig ON mig.index_handle = mid.index_handle
ORDER BY mig.index_group_handle, mig.index_handle, column_id;
圖五
總結
n 基於這個例子我們可以看到,我們可以在表AdventureWorks.Person.Address的字段StateProvinceID上創建一個新索引,也可以包括columns City和PostalCode。
n 要注意的是當你在一張表中增加或者刪除索引時,缺失索引的所有統計數據將在這張表中完全清除。
n 盡管這可能不是完美的,也存在一些局限,但是這至少讓我們了解了之前使用SQL Server舊版本時從來不知道的信息。