【发布时间】:2017-04-01 17:22:07
【问题描述】:
我在名为Shopper 的表上有两个索引。
聚集索引:
CREATE CLUSTERED INDEX [CI_EMail_ShopperNumID]
ON [dbo].[Shopper] ([EMail] ASC, [ShopperNumID] ASC)
非聚集索引
CREATE NONCLUSTERED INDEX [nci_wi_Shopper_D8E9A1BB0660D0838F923BB8587C7115]
ON [dbo].[Shopper] ([EMail] ASC)
INCLUDE ([DateCreated], [FirstName], [LastLoginDate], [LastName],
[MaxEmailVolume], [ShopperNumID], [ShopperSourceCD], [ShopperSourceOther])
我运行了一个非常简单的SELECT:
SELECT ShopperNumID
FROM shopper
WHERE Email = '87.kl@abcxyz.com'
在分析执行计划时,我注意到正在使用非聚集索引:
现在,我删除非聚集索引:
DROP INDEX IF EXISTS [nci_wi_Shopper_D8E9A1BB0660D0838F923BB8587C7115]
ON [dbo].[Shopper]
GO
然后重新运行我的选择以注意到聚集索引(最终)正在被使用
谁能解释一下为什么优化引擎使用的是(庞大的)非聚集索引,而不是(首选的)聚集索引?
Microsoft SQL Server 2016 (RTM-GDR) (KB3194716) - 13.0.1722.0 (X64)
Windows 10 Pro 6.3(内部版本 14393:)上的开发者版(64 位)
更新: 根据收到的输入,为了进一步评估,我在表上创建了另一个非聚集索引,与现有的聚集索引非常相似。
CREATE NONCLUSTERED INDEX [NCI_EMail_ShopperNumID]
ON [dbo].[Shopper] ([EMail] ASC, [ShopperNumID] ASC)
目前该表有3个索引可以支持我的SELECT:
- 聚集索引 [CI_EMail_ShopperNumID]
- 非聚类索引 [nci_wi_Shopper_D8E9A1BB0660D0838F923BB8587C7115]
- 非集群索引 [NCI_EMail_ShopperNumID]
现在,当我运行相同的SELECT:
SELECT ShopperNumID
FROM shopper
WHERE Email = '87.kl@abcxyz.com'
无论如何,优化器似乎都坚持使用非聚集索引!
【问题讨论】:
-
聚集索引并不是真正的索引,它是表本身。因此,它包含所有表列,索引列仅定义存储数据的排序顺序。
-
您的非集群覆盖索引的用例是什么?鉴于它只包含 [email] 列,并且假设它存储在同一个文件组上,它不会比 CLUSTERED 索引的性能有所提高。
-
我很好奇 - 哪一个实际上更快? (清除缓存后)。
SET STATISTICS IO是否显示任何特别不同的输出? -
@Nick.McDermaid -
Table 'Shopper'. Scan count 1, logical reads 3, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.使用任一索引时,STATISTICS IO输出相同。理想情况下,无论使用什么索引,执行时间都不会受到影响,因为正在寻找(而不是扫描)值。
标签: sql sql-server indexing sql-execution-plan