您能否向我解释为什么在查询聚簇索引时查询时未使用此非聚簇索引?
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上设置顺序,则使用index。
这很容易重现。
只需将以下虚拟数据插入到您问题中的表格中......
insert into [dbo].[table]
SELECT TOP 1000000 DATEADD(SECOND, CRYPT_GEN_RANDOM(4)% 1000000,GETDATE()) , 1, 1, 1, 1
FROM sys.all_objects o1, sys.all_objects o2
然后跑
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
OPTION (QUERYTRACEON 9130) /*so filter visible in the plan*/
SELECT TOP 10 npl.NPId
FROM [table] npl WITH (INDEX = IX_ReqDate)
WHERE npl.RequestDate >= @date
AND npl.RequestDate < @date2
ORDER BY npid
以上是使用CardinalityEstimationModelVersion = 140
- 类似的将在CE的其他版本中看到,虽然确切的数字可能是不同的。
16.431676725155%
行(0.30*SQRT(0.30)
)。10/(0.30*SQRT(0.30))
)。您可以尝试添加OPTION (RECOMPILE)
,以便SQL Server嗅探变量使用的日期范围,并且可以将16.4%的估计值降低到足以更改计划。
但是,可能更有可能的是,估计值会降低但不足以更改计划,CI计划仍然不足(因为匹配范围的行不会在整个表中均匀分布,并且必须读取的行数多于估计值)。在这种情况下,您可以考虑使用索引提示来获取所需的索引。