1. 程式人生 > 其它 >SQL Server 索引優化 ——索引缺失

SQL Server 索引優化 ——索引缺失

sys.dm_db_missing_index_details缺失索引明細,包括相等列,不等列以及包含列,執行如下指令碼,並檢視結果

1 USE [testDB] 
2 GO
3 SELECT * FROM sys.dm_db_missing_index_details;

從結果可以看出,所有資料庫中,缺失索引的表或索引檢視都被列出來了。但是否需要把列出來的缺失索引都直接建上去呢?

顯然,這樣做可能不但不能提升效能,還可能會導致效能下降。

如: 有些查詢是偶發性的,使用率極低,而對應的表又有大量的插入、更新等;或者某些索引的建立對效能本身提升不多;

又或者,缺失索引的列,在某些儲存的索引中已經部分包含,按照缺失索引給出資訊去建立,會造成索引冗餘。

結合以上情形,如果我們想補缺失索引,那麼我們還需要知道缺失索引使用的頻率,對效能的提升等資訊。

動態檢視sys.dm_db_missing_index_group_stats給出了我們需要的資訊,

下面我們給出缺失索引的狀態

1 SELECT OBJECT_NAME(m.OBJECT_ID) tableName,equality_columns,inequality_columns,included_columns,
2 unique_compiles,user_seeks,user_scans,avg_user_impact,avg_system_impact
3 FROM sys.dm_db_missing_index_details m
4 LEFT JOIN sys.dm_db_missing_index_groups g ON m.index_handle=g.index_handle 5 LEFT JOIN sys.dm_db_missing_index_group_stats s ON g.index_group_handle=s.group_handle 6 WHERE m.database_id=DB_ID();

我們可以根據上面查詢的結果,使用者查詢、使用者掃描次數,使用者效能影響,初步判斷需要的索引。

最終還要根據已經存在的索引,以及索引建立的一些規則,確定需要新建立的索引。

建立指令碼:

 1 SELECT TOP 100
2 statement AS 表 , 3 equality_columns AS 相等列 , 4 inequality_columns AS 不相等列 , 5 included_columns AS 包含列 , 6 user_scans + user_seeks AS 總查詢次數 , 7 avg_user_impact AS 平均百分比收益 , 8 avg_total_user_cost AS 平均成本 , 9 avg_total_user_cost * avg_user_impact * ( user_scans + user_seeks ) AS 可能改進 , 10 'CREATE INDEX [index_' + obj.name + '_' 11 + CONVERT(VARCHAR(32), GS.group_handle) + '_' 12 + CONVERT(VARCHAR(32), D.index_handle) + ']' + ' ON ' + [statement] 13 + ' (' + ISNULL(equality_columns, '') 14 + CASE WHEN equality_columns IS NOT NULL 15 AND inequality_columns IS NOT NULL THEN ',' 16 ELSE '' 17 END + ISNULL(inequality_columns, '') + ')' + ISNULL(' INCLUDE (' 18 + included_columns 19 + ')', '') AS Create_Index_Syntax 20 FROM sys.dm_db_missing_index_details AS D 21 INNER JOIN sys.dm_db_missing_index_groups G ON G.index_handle = D.index_handle 22 INNER JOIN sys.dm_db_missing_index_group_stats GS ON G.index_group_handle = GS.group_handle 23 INNER JOIN sys.objects AS obj ON obj.object_id = OBJECT_ID([statement]) 24 AND obj.type = 'U'