首页 > 解决方案 > 在日期列中使用 NULL 时,多索引的 SQL Server 统计信息不正确

问题描述

SQL Server 有一个关于索引的统计信息,它错误地估计了行数,这个表(和谓词)用于许多不同的查询。这会导致这些查询执行不佳,因为统计数据期望查询返回 5 行,而它返回 431268。

查询:

SELECT COUNT(BuildRecord.BuildRecordID)
FROM dbo.BuildRecord
WHERE BuildRecord.ContainedToDT IS NULL
  AND BuildRecord.RfBuildRecordTypeID = 2 
  AND BuildRecord.IsEdited = 0

执行计划

昨天用 FULLSCAN 更新了统计数据:

指数统计

索引的碎片<1%。

BuildRecord表中,ContainedToDT是 NULLABLE DATETIMEOFFSETRfBuildRecordTypeID是 NOT-NULLSMALLINT并且IsEdited是 NOT-NULL TINYINT

指数如下:

CREATE NONCLUSTERED INDEX [IM_ContainedToDT_RfBuildRecordTypeID_IsEdited] 
ON [dbo].[BuildRecord] ([ContainedToDT] ASC, [RfBuildRecordTypeID] ASC, [IsEdited] ASC)
INCLUDE([InvPackCreatedID], [InvPackConsumedID]) 
       WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
             SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, 
             ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]

SQL Server 版本为 Microsoft SQL Server 2019 (RTM-CU8) (KB4577194) 兼容模式为 SQL Server 2016 (130)

任何建议或想法将不胜感激。

标签: sql-serverdatabase-indexes

解决方案


将兼容模式更改为 SQL Server 2019 (150) 似乎可以让我更好地估计这个统计数据。

2019兼容模式执行计划

强制查询使用 Legacy Cardinality Estimation 传统基数估计


推荐阅读