缺少索引未显示在执行计划中

Ada*_*arp 7 sql-server ssms sql-server-2014

我最近安装了SQL Server Management Studio 2014 (Developer Edition),我注意到我不再看到缺少的索引功能。

我做了什么:

  • 通过Database Engine Tuning Advisor 运行工作负载,因此我知道该表缺少索引。
  • 在网上找不到任何关于启用该功能的信息
  • 筛选每个似乎相关的选项。

任何建议将不胜感激。在 2014 年之前,我之前运行的是SQL Server 2012 Developer Edition

更新

在某些情况下,我能够让它显示缺失的索引。看看这两个查询:

对于此查询,执行计划中没有显示缺失的索引。WHERE 子句字段是 varchar(512) 并且在此列上没有索引。

SELECT SomeVarchar FROM SomeTable WHERE Name='Adam'
Run Code Online (Sandbox Code Playgroud)

对于此查询,它显示执行计划中缺少索引。年龄是一个INT

SELECT SomeVarchar20 FROM SomeTable WHERE Age=30
Run Code Online (Sandbox Code Playgroud)

缺失索引:

CREATE NONCLUSTERED INDEX [<Name of Missing Index, sysname,>]
ON [dbo].[SomeTable] ([Age])
INCLUDE ([SomeVarchar20])
Run Code Online (Sandbox Code Playgroud)

我还尝试了一个带有VARCHAR(500)字段的查询,它确实返回了一个缺失的索引。我现在真的在挠头。

Ion*_*nic 9

好吧,虽然您的 Tuning Advisor 显示缺少索引,但这并不意味着您当前正在运行的查询将从该索引中受益。如果当前计划将从索引中受益,则只会显示缺失的索引。

您还可以查看其中一个DMV,它们将显示当前数据库缺少的索引。

SELECT *
FROM sys.dm_db_missing_index_details
Run Code Online (Sandbox Code Playgroud)

如果您需要更多信息,也可以使用我提供的此查询:

SELECT  id.index_handle, DB_NAME(id.database_id), id.object_id, id.statement AS object_name, 
        gs.avg_user_impact, gs.avg_total_user_cost,
        id.equality_columns, id.inequality_columns, id.included_columns,
        gs.unique_compiles, gs.user_seeks, gs.last_user_seek, gs.last_system_seek, 
        gs.user_scans, gs.last_user_scan, gs.system_scans
FROM sys.dm_db_missing_index_details as id
INNER JOIN sys.dm_db_missing_index_groups as g
        ON id.index_handle = g.index_handle
INNER JOIN sys.dm_db_missing_index_group_stats as gs
        ON g.index_group_handle = gs.group_handle
ORDER BY gs.avg_user_impact DESC
Run Code Online (Sandbox Code Playgroud)

根据上次更新进行编辑

那么很容易确定为什么你不会得到建议。

首先,为什么你会得到这个查询的建议索引:

SELECT SomeVarchar20 FROM SomeTable WHERE Age=30
Run Code Online (Sandbox Code Playgroud)

如果您按照下面的建议创建索引,您将完全在索引之外提供索引。

CREATE NONCLUSTERED INDEX [<Name of Missing Index, sysname,>]
ON [dbo].[SomeTable] ([Age])
INCLUDE ([SomeVarchar20])
Run Code Online (Sandbox Code Playgroud)

SQL Server 将能够使用Age索引中定义的搜索数据页。此外,由于您只选择了列SomeVarchar20,因此建议添加到您的索引的叶级页面(由 定义INCLUDE)。这将帮助 SQL Server 基于AgeB 树架构中的找到正确的页面。在他找到最后一行(其中包含指向 HEAP 或所有其他属性所在的聚集索引)的指针后,他还可以找到叶级页面上包含的列。由于他在索引本身中找到了要显示的所有内容,因此他不会进一步访问您的 HEAP 或聚集索引。这将大大提高您的读取 (!) 性能。

事实上,我很清楚为什么您不会得到向该列添加索引的建议:

SELECT SomeVarchar FROM SomeTable WHERE Name='Adam'
Run Code Online (Sandbox Code Playgroud)

你说你的 ColumnName是一个varchar(512)这意味着一个值可以是 512 字节长。事实上,一个 SQL Server 页面可以容纳大约 8060 个字节。这意味着每页最多可以存储 16 个名称(如果不一直使用 512 字节,可能会更多)。这不会显着提高性能,因为 SQL Server 甚至可能需要迭代(查找)许多页面。事实上,他需要在每个insert/update/delete.

如果你只是使用SomeVarchar,这可能也是一个varchar(512),它会大大提高叶级页面,这会使索引效率更低。这就是为什么您的 SQL Server 可能不会为您的SELECT.

希望这会清除你脑海中的所有其他事情。否则让我知道。