由於有了很多新功能,我們可以看到在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_missing_index_group_stats中擷取資料。這個查詢使我們更瞭解其他統計資料,例如編譯,使用者尋找, 使用者掃描等,所以從這裡我們可以知道這個查詢多久會被訪問。如果我們建立一個基於這些資訊的新索引,這將協助我們確定多久使用一個索引可以獲得資料。
SELECT * FROM sys.dm_db_missing_index_group_stats
由於這個查詢我們只執行了一次,因此我們的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舊版本時從來不知道的資訊。