为什么SQL Server 2012推荐创建这个索引?

Ran*_*der 4 sql-server

我有以下查询:

Select SubId, Max(ReadTimeLocal)
From dbo.PanelWorkflow 
Where ProcessNumber IN (802,1190,1605,1620,1645,1660,1695,1790,1990,2690,2795,2990,3090,3290,3590,3790,4190,4390,4590,5000,5200,5400)
Group By SubId
Run Code Online (Sandbox Code Playgroud)

我在 dbo.PanelWorkflow 表上有以下索引:

CREATE NONCLUSTERED INDEX [IX_PanelWorkflow_ProcessNumber_Lineage] ON [dbo].[PanelWorkflow]
(
    [ProcessNumber] ASC,
    [Lineage] ASC
)
INCLUDE ( [SubId],[ReadTimeLocal]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
Run Code Online (Sandbox Code Playgroud)

来自 SSMS 的查询计划如下所示:

在此处输入图片说明

SSMS 建议我创建以下索引(影响为 54.3)

CREATE NONCLUSTERED INDEX [<Name of Missing Index, sysname,>]
ON [dbo].[PanelWorkflow] ([ProcessNumber])
INCLUDE ([SubId],[ReadTimeLocal])
Run Code Online (Sandbox Code Playgroud)

有谁知道为什么它建议我创建一个基本上已经存在的索引,而不是使用确实存在的索引?

表中有 8.3 亿行。使用 SQL Server 2012。

小智 5

澄清一下,SSMS 不推荐该索引,它来自查询引擎/优化器。还要注意,一篇好的 MSDN 文章指出了 Missing Index Feature 的一些限制

您当前的非聚簇索引包含的事实[ProcessNumber][Lineage]查询引擎发现,只需扫描表的聚簇索引即可获得最佳效果。它建议严格使用索引,ProcessNumber因为查询仅在该列上进行过滤。我相信如果这也是聚集索引所基于的列,那么查询优化器将忽略您的非聚集索引。

我会查看优化器为该表看到的所有缺失索引,并评估当前未使用的索引。


Aar*_*and 5

似乎 SQL Server 只是推荐一个比现有索引更好地覆盖查询的更薄的索引(并且目前无论如何都选择了聚集索引)。我不确定数据类型Lineage是什么,但似乎认为从该索引读取数据会很浪费。即使建议使用更薄的索引,我也不知道您的查询是否仍然可以通过搜索满足,因此与您现在拥有的相比,它不太可能提供巨大的改进。如果这是一个常见的查询(意味着这些是ProcessNUmber你总是查询的相同值),你可以考虑一个过滤索引:

CREATE INDEX IX_SubID ON dbo.PanelWorkflow(SubID, ReadTimeLocal DESC)
  WHERE ProcessNumber IN (802,1190,...);
Run Code Online (Sandbox Code Playgroud)