透過Total Cost (s.avg_total_user_cost * s.avg_user_impact * (s.user_seeks + s.user_scans))來找出前幾個影響比較大的索引,然後建立遺漏索引。
在「SQL Server 動態管理檢視和函數」一篇中,我們可透過 動態管理檢視和函數(DMV) 來找出SQL運行中,遺漏索引的資訊。
透過Total Cost (s.avg_total_user_cost * s.avg_user_impact * (s.user_seeks + s.user_scans))來找出前幾個影響比較大的索引。
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT TOP 20
ROUND(s.avg_total_user_cost *
s.avg_user_impact
* (s.user_seeks + s.user_scans),0)
AS [Total Cost]
, d.[statement] AS [Table Name]
, equality_columns
, inequality_columns
, included_columns
FROM sys.dm_db_missing_index_groups g
INNER JOIN sys.dm_db_missing_index_group_stats s
ON s.group_handle = g.index_group_handle
INNER JOIN sys.dm_db_missing_index_details d
ON d.index_handle = g.index_handle
ORDER BY [Total Cost] DESC
透過上面的結果,可以幫助我們建立以下的索引
CREATE NONCLUSTERED INDEX IX_YOUR_INDEX_NAME
ON YOUR_TABLENAME(equality_columns, inequality_columns)
INCLUDE (included_columns)
不過,剛開始,我們可以先針對included_columns及inequality_columns欄位值是NULL的資料來建立索引,如下,
CREATE NONCLUSTERED INDEX IX_YOUR_INDEX_NAME
ON YOUR_TABLENAME(equality_columns)
如果inequality_columns欄位值不是NULL的話,表示SQL查詢有 = 以外的其他任何比較運算子。可以查一下SQL是不是有寫 <> ,看看是否能加以調整,如以 EXISTS 代替。
如果included_columns的欄位很多的話,就要注意,程式中是不是有SQL是寫SELECT * FROM YOURTABLE,要找出來加以調整哦!
另外要注意,加入了索引,針對某些查詢效能會比較好,但是會影響(INSERT/UPDATE/DELETE)的效能。所以在加完索引後,要加以測試看看,以取得2邊的平衡點。
參考資料
sys.dm_db_missing_index_details
sys.dm_db_missing_index_groups
sys.dm_db_missing_index_group_stats
Hi,
亂馬客Blog已移到了 「亂馬客 : Re:從零開始的軟體開發生活」
請大家繼續支持 ^_^