【发布时间】:2019-09-12 15:17:47
【问题描述】:
您能否向我解释一下为什么在查询和对聚集索引进行排序时不使用此非聚集索引?
CREATE TABLE [dbo].[table]
(
[NPId] [BIGINT] IDENTITY(1,1) NOT NULL,
[RequestDate] [DATETIME2](2) NOT NULL,
[Status] [TINYINT] NOT NULL,
[StatusCodeId] [SMALLINT] NULL,
[NumberCount] [INT] NULL,
[Number] [BIGINT] NULL,
CONSTRAINT [PK_NPLog_1]
PRIMARY KEY CLUSTERED ([NPId] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE NONCLUSTERED INDEX [IX_ReqDate]
ON [dbo].[table] ([RequestDate] ASC)
INCLUDE ([NPId])
查询:
DECLARE @date datetime2(2) = '2018.07.10'
DECLARE @date2 datetime2(2) = '2018.08.10'
SELECT TOP 10 npl.NPId
FROM [table] npl
WHERE npl.RequestDate >= @date
AND npl.RequestDate < @date2
ORDER BY npid
如果我在 requestDate 上设置顺序,则使用索引。
【问题讨论】:
-
所以 SQL Server 决定过滤器比
order by更重要。 -
表格有多少行?如果有太多,那么 SQL Server 可能会发现处理由 npid 排序的行希望找到前 10 个匹配行是有效的。
-
考虑到您通过
NPid订购并返回TOP 10,我猜估计器认为 CLUSTERED 索引是更好的选择。如果这是它得出的结论,它可能就是这样。 -
SQL Server 将估计 30% 的行匹配
RequestDate谓词(因为实际值被变量隐藏,所以它必须猜测)并且它们在表中均匀分布,因此它只需要阅读33以获取由NPId订购的TOP 10。实际上,由于日期范围只有一个月,因此匹配百分比可能要低得多,并且它们可能与 w.r.t. 相关。NPId所以它们都聚集在一起,这不是一个好计划......另一种方法是对匹配RequestDate范围的所有行进行排序,然后得到TOP 10,这可能成本更高 -
实际上 30% 是用于单个不等式谓词的猜测。对于
>=和<,它会略低(0.3) * SQRT(0.3) = 16.4%(dependant on CE version) - 所以估计61行以获得TOP 10
标签: sql-server indexing b-tree