来自 SQL Server Management Studio 的令人困惑的性能建议

Confusing performance advice from SQL Server Management Studio

我正在努力提高我们的 SQL-性能。 SQL Server Management Studio 给出了一个令我惊讶的建议。为了示例,我将简化 table 结构和 SSMS 给出的建议。

Table 人的结构:

我有一个特定的查询,我为其显示了执行计划。然后我看到了SSMS给的建议,让我有点吃惊。建议添加两个具有以下签名的索引,它们应该分别提高 41% 和 53% 的性能:

CREATE NONCLUSTERED INDEX [person_1]
  ON [Person]([first_name],[last_name])
  INCLUDE ([id],[date_of_birth],[email])

CREATE NONCLUSTERED INDEX [person_2]
  ON [Person]([first_name],[last_name])
  INCLUDE ([id],[email])

这两个索引在同一列上。只有 INCLUDE 列不同。我从阅读索引中了解到,第一个索引也包含第二个索引的数据。那么为什么SSMS推荐第二个索引,而第一个索引已经包含了需要的数据呢?

切勿理所当然地使用 SSMS 建议。该建议基于特定查询。

而是探索像 sys.dm_db_missing_index_details 这样的系统视图。 查看更多 sys.dm_db_missing_index_details

或在 SQL Server Diagnostic Information Queries for April 2019

上查看 Glenn Berry 的 DMV 查询

... 甚至更好选择 Brent Ozar sp_blitzindex BrentOzarULTD/SQL-Server-First-Responder-Kit

... 或进行此查询

SELECT DB_NAME(database_id) AS database_name, 
       OBJECT_NAME(object_id, database_id) AS table_name, 
       mid.equality_columns, 
       mid.inequality_columns, 
       mid.included_columns, 
       (migs.user_seeks + migs.user_scans) * migs.avg_user_impact AS Impact, 
       migs.avg_total_user_cost * (migs.avg_user_impact / 100.0) * (migs.user_seeks + migs.user_scans) AS Score, 
       migs.user_seeks, 
       migs.user_scans
FROM sys.dm_db_missing_index_details mid
     INNER JOIN sys.dm_db_missing_index_groups mig ON mid.index_handle = mig.index_handle
     INNER JOIN sys.dm_db_missing_index_group_stats migs ON mig.index_group_handle = migs.group_handle
ORDER BY migs.avg_total_user_cost * (migs.avg_user_impact / 100.0) * (migs.user_seeks + migs.user_scans) DESC;