Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 2008 为什么选择计数(*)执行聚集索引扫描?_Sql Server 2008_Count_Clustered Index - Fatal编程技术网

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,为什么使用非聚集索引进行计数操作会比使用聚集索引更快?