1

有些东西激起了我的好奇心(虽然我的代码没有问题,只是一个普遍的问题)。SQL Server 中的聚合函数究竟是如何工作的?它背后的机制是什么?

假设我们有一个包含 999,999,999 行的表,我们只想获取该表中的行数。

SELECT Count(*)
FROM   <Table>

此聚合函数是否会逐行扫描整个表以获取该表中的行数,或者是否有一个内部表在从该表中添加/删除行时跟踪其中的行数(访问通过系统存储过程)并且像这样的函数会使用更多的 CPU 还是会使用更多的 I/O 读/写时间?

PS 我读了这个 MSDN 站点,但很遗憾它没有回答我的问题。

谢谢

4

2 回答 2

3

只是一个简短的说明:count(*)在 SQL Server 中询问元数据。当您考虑未提交事务的隔离级别和行可见性时,查询元数据count(*)是完全不正确的。此外,在某些条件下,元数据行数可能会偏离实际行数(旧版本更多,新版本更少)。具体条件无关,但考虑一下为什么 DBCC UPDATEUSAGE有一个COUNT_ROWS子句:

指定行计数列使用表或视图中的当前行数计数进行更新。

话虽如此,聚合是如何实现的?首先,我建议阅读有关Volcano执行模型的信息。是一篇冗长的论文,但对于理解大多数关系数据库的逐行执行模型至关重要。接下来我推荐阅读这篇博文Stream Aggregate。它的要点是流聚合需要一个排序的输入,并且在排序的输入上很容易计算任何聚合(顺便说一句。有众所周知的单次方差算法,唯一一个没有明显的琐碎实现的算法)。

为了完整起见,这里是流式聚合丑陋姐妹内存猪替代品的链接:哈希聚合

于 2013-04-02T11:00:42.793 回答
2

如果可能,它将运行和索引扫描,否则将运行表扫描。

Set SHOWPLAN_TEXT on
go
SELECT Count(*)
FROM   <Table>
于 2013-04-02T10:24:51.813 回答