Sql 为什么在计算表中的所有行时会进行非聚集索引扫描?

Sql 为什么在计算表中的所有行时会进行非聚集索引扫描?,sql,sql-server,Sql,Sql Server,据我所知,每个事务都会看到它自己的数据库版本,因此系统无法从某个计数器获取行的总数,因此需要扫描索引。但是我认为它应该是主键上的聚集索引,而不是附加索引。如果我有多个附加索引,那么会选择哪一个 在深入研究这件事时,我注意到了另一件奇怪的事。假设有两个相同的表,Articles和Articles2,每个表有三列:Id、View\u Count和Title。第一个索引只有一个基于聚集PK的索引,而第二个索引在视图计数上有一个额外的非聚集、非唯一索引。对于具有附加索引的表,查询SELECT COUNT

据我所知,每个事务都会看到它自己的数据库版本,因此系统无法从某个计数器获取行的总数,因此需要扫描索引。但是我认为它应该是主键上的聚集索引,而不是附加索引。如果我有多个附加索引,那么会选择哪一个


在深入研究这件事时,我注意到了另一件奇怪的事。假设有两个相同的表,Articles和Articles2,每个表有三列:Id、View\u Count和Title。第一个索引只有一个基于聚集PK的索引,而第二个索引在视图计数上有一个额外的非聚集、非唯一索引。对于具有附加索引的表,查询
SELECT COUNT(1)FROM Articles
的运行速度要快2倍

SQL Server将优化您的查询-如果需要计算表中的行数,它将选择尽可能最小的数据集

所以如果你考虑你的聚集索引——它包含实际的数据页——可能每行几千个字节。加载所有这些字节只是为了计算行数是浪费的——即使只是在磁盘I/O方面也是如此


因此,如果有一个非聚集索引没有以任何方式进行过滤或限制,SQL Server将选择该数据结构进行计数-因为非聚集索引基本上包含您放入NC索引中的列(加上聚集索引键)-仅为了计算行数而加载的数据要少得多。

是的,当我发布第二部分并更仔细地查看计划时,我发现了这一点。聚集索引扫描的CPU成本相同,但IO成本较高。