我曾经读过一些文章,说当表有很多行和很多列时,SELECT COUNT(*) FROM TABLE_NAME将会很慢。

我有一个可能包含数十亿行的表(它大约有15列)。有没有更好的方法来获得一个表的行数的精确计数?

在回答之前请考虑以下问题:

我正在寻找一个数据库供应商 独立的解决方案。如果是也可以 涵盖MySQL, Oracle, MS SQL Server。 但如果真的没有数据库 供应商独立的解决方案,然后我 会接受不同的解决方案吗 针对不同的数据库供应商。 我不能使用任何外部工具 这样做。我主要是在找一个 基于SQL的解决方案。 我不能规范化我的数据库设计 任何进一步的。它已经在3NF中,而且 很多代码已经写好了 围绕它。


当前回答

如果你有一个典型的表结构,其中有一个自动递增的主键列,其中的行永远不会被删除,下面的方法将是确定记录计数的最快方法,并且应该在大多数ANSI兼容的数据库中类似地工作:

SELECT TOP(1) <primarykeyfield> FROM <table> ORDER BY <primarykeyfield> DESC;

我使用的MS SQL表包含数十亿行,需要亚秒级的数据响应时间,包括记录计数。通过比较,类似的SELECT COUNT(*)将花费数分钟来处理。

其他回答

如果你有一个典型的表结构,其中有一个自动递增的主键列,其中的行永远不会被删除,下面的方法将是确定记录计数的最快方法,并且应该在大多数ANSI兼容的数据库中类似地工作:

SELECT TOP(1) <primarykeyfield> FROM <table> ORDER BY <primarykeyfield> DESC;

我使用的MS SQL表包含数十亿行,需要亚秒级的数据响应时间,包括记录计数。通过比较,类似的SELECT COUNT(*)将花费数分钟来处理。

我使用

select /*+ parallel(a) */  count(1) from table_name a;

使用SQL Server 2019,您可以使用APPROX_COUNT_DISTINCT,它:

返回组中唯一非空值的大致数目

医生说:

APPROX_COUNT_DISTINCT是为大数据场景而设计的 针对以下条件进行优化: 访问数百万行或更高的数据集 一个或多个具有不同值的列的聚合

还有,函数

实现保证在97%的概率内高达2%的错误率 比穷举COUNT DISTINCT操作需要更少的内存 与精确的COUNT DISTINCT操作相比,较小的内存占用不太可能将内存溢出到磁盘。

该算法背后实现了HyperLogLog。

PostgreSQL:

SELECT reltuples AS approximate_row_count FROM pg_class WHERE relname = 'table_name'

到目前为止,MySQL上最快的方法是:

SHOW TABLE STATUS;

您将立即获得所有表的行数(即总数)以及大量额外信息(如果需要的话)。