Sql server 2008 为什么选择计数(*)执行聚集索引扫描?
我有下表:Sql server 2008 为什么选择计数(*)执行聚集索引扫描?,sql-server-2008,count,clustered-index,Sql Server 2008,Count,Clustered Index,我有下表: 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
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]
我正在尝试执行一个查询:
SELECT COUNT(*)
FROM Addr
当表包含大约800万条记录时,它立即执行。但现在这个表包含2100万条记录,查询的执行速度非常慢。Managemet Studio显示下一个预计计划:
存储选项卡的屏幕截图(表属性):
我使用的是
MSSQL 2008 Express 10.50.1617.0
。为什么这个简单的查询有这么复杂的计划?这个计划一点也不复杂。要计算记录数,引擎必须扫描整个表,但由于有聚集索引,所以它使用它。如果没有聚集索引,thre将是表扫描
,而不是聚集索引扫描
。如果您在任何列上都有非聚集索引,优化器很可能会选择该索引来计算记录,并且操作会更快。这可能暴露了我自己对SQL Server的无知,但是您从Addr选择计数(地址)有什么计划?(如果他们不一样,我会感到震惊,只是好奇。)计划与从Addr选择计数(地址)的是一样的,可能是表现在已经被分区了吗?有多慢是“非常慢”?您还可能遇到来自其他事务的阻塞。特别是如果它似乎从来没有结束过,那么情况很可能就是这样。“非常慢”-我等待3分钟,然后终止一个查询。没有其他事务。但如何解释,当表中包含800万条记录时,此查询立即执行?@Zergatul:也许您已经越过了索引在内存中的位置。@Zergatul-可能当时页面都在缓存中。它仍然会有一个计数为800万行的CI扫描。@Zergatul打开统计IO
,然后运行查询。我看到您使用的是Express Edition,因此它的数据缓存限制为1GB,并且不使用预读将页面带入缓存。如果需要,还可以检查CI和碎片整理上的碎片级别。可能会有一些改进。@Adam,为什么使用非聚集索引进行计数操作会比使用聚集索引更快?