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

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

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

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


当前回答

我不认为有一个通用的总是最快的解决方案:一些RDBMS/版本对SELECT COUNT(*)进行了特定的优化,使用更快的选项,而其他版本只是简单的表扫描。对于第二组,您需要访问文档/支持站点,这可能需要编写一些更具体的查询,通常是以某种方式命中索引的查询。

编辑:

Here's a thought that might work, depending on your schema and distribution of data: do you have an indexed column that references an increasing value, a numeric increasing ID, say, or even a timestamp or date? Then, assuming deletes don't happen, it should be possible to store the count up to some recent value (yesterday's date, highest ID value at some recent sample point) and add the count beyond that, which should resolve very quickly in the index. Very dependent on values and indices, of course, but applicable to pretty much any version of any DBMS.

其他回答

有没有更好的方法来获得一个表的行数的精确计数?

简单地回答你的问题,没有。

如果你需要一个独立于DBMS的方法来做这件事,最快的方法总是:

SELECT COUNT(*) FROM TableName

一些DBMS供应商可能有更快的方法,只适用于他们的系统。其中一些选项已经在其他答案中发布了。

COUNT(*)应该由DBMS(至少是任何值得PROD的DB)进行优化,所以不要试图绕过它们的优化。

On a side note: I am sure many of your other queries also take a long time to finish because of your table size. Any performance concerns should probably be addressed by thinking about your schema design with speed in mind. I realize you said that it is not an option to change but it might turn out that 10+ minute queries aren't an option either. 3rd NF is not always the best approach when you need speed, and sometimes data can be partitioned in several tables if the records don't have to be stored together. Something to think about...

如果使用插入触发器代价太大,但可以使用删除触发器,并且有一个自动递增的id,那么在对整个表进行一次计数后,将计数记为last-count和last- counts -id,

然后每天只需要为id > last- counting -id计数,将其添加到last-count中,并存储新的last- counting -id。

如果被删除记录的id <= last-count -id,删除触发器将递减last-count。

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

SHOW TABLE STATUS;

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

我不认为有一个通用的总是最快的解决方案:一些RDBMS/版本对SELECT COUNT(*)进行了特定的优化,使用更快的选项,而其他版本只是简单的表扫描。对于第二组,您需要访问文档/支持站点,这可能需要编写一些更具体的查询,通常是以某种方式命中索引的查询。

编辑:

Here's a thought that might work, depending on your schema and distribution of data: do you have an indexed column that references an increasing value, a numeric increasing ID, say, or even a timestamp or date? Then, assuming deletes don't happen, it should be possible to store the count up to some recent value (yesterday's date, highest ID value at some recent sample point) and add the count beyond that, which should resolve very quickly in the index. Very dependent on values and indices, of course, but applicable to pretty much any version of any DBMS.

嗯,晚了5年,不确定这是否有帮助:

我在试着数不。在SQL Server表中使用MS SQL Server Management Studio的行,并遇到了一些溢出错误,然后我使用下面的:

select count_big(1) FROM [dbname].[dbo].[FactSampleValue];

结果:

24296650578行