为什么SELECT COUNT(*)执行聚簇索引扫描?

Zer*_*tul 4 count clustered-index sql-server-2008

我有下表:

CREATE TABLE [dbo].[Addr](
    [Address] [char](34) NOT NULL,
 CONSTRAINT [PK_Addr] PRIMARY KEY CLUSTERED 
(
    [Address] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
Run Code Online (Sandbox Code Playgroud)

我正在尝试执行查询:

SELECT COUNT(*)
FROM Addr
Run Code Online (Sandbox Code Playgroud)

当表包含大约800万条记录时,它立即执行.但是现在表包含2100万条记录,而查询执行速度非常慢.Managemet Studio显示下一个估计的计划:

执行计划

"存储"选项卡(表格属性)的屏幕截图

在此输入图像描述

我在用MSSQL 2008 Express 10.50.1617.0.为什么这个简单的查询有这么复杂的计划

Ada*_*ski 5

这个计划根本不复杂.要计算记录数,引擎必须扫描整个表,但由于存在聚簇索引,因此它使用它.如果没有聚集索引,则可以Table Scan代替Clustered Index Scan.如果您在任何列上都有非聚集索引,优化器很可能会选择该索引来计算记录,并且操作会更快.

  • @Zergatul - 可能这些页面都在缓存中.它仍然会有一个CI扫描计数800万行. (3认同)
  • @Zergatul:也许你已经超越了索引适合记忆的程度. (2认同)
  • @Zergatul`SET STATISTICS IO ON`然后运行您的查询.我发现你使用的是Express Edition,因此限制为1GB的数据缓存,也不使用预读将页面置于缓存中.您还可以检查CI上的碎片级别,并根据需要进行碎片整理.可能会有所改善. (2认同)