我曾经读过一些文章,说当表有很多行和很多列时,SELECT COUNT(*) FROM TABLE_NAME将会很慢。
我有一个可能包含数十亿行的表(它大约有15列)。有没有更好的方法来获得一个表的行数的精确计数?
在回答之前请考虑以下问题:
我正在寻找一个数据库供应商
独立的解决方案。如果是也可以
涵盖MySQL, Oracle, MS SQL Server。
但如果真的没有数据库
供应商独立的解决方案,然后我
会接受不同的解决方案吗
针对不同的数据库供应商。
我不能使用任何外部工具
这样做。我主要是在找一个
基于SQL的解决方案。
我不能规范化我的数据库设计
任何进一步的。它已经在3NF中,而且
很多代码已经写好了
围绕它。
我从另一个StackOverflow问题/答案得到这个脚本:
SELECT SUM(p.rows) FROM sys.partitions AS p
INNER JOIN sys.tables AS t
ON p.[object_id] = t.[object_id]
INNER JOIN sys.schemas AS s
ON s.[schema_id] = t.[schema_id]
WHERE t.name = N'YourTableNameHere'
AND s.name = N'dbo'
AND p.index_id IN (0,1);
我的表有5亿条记录,上面的返回时间不到1毫秒。
与此同时,
SELECT COUNT(id) FROM MyTable
整整39分52秒!
它们产生的行数完全相同(在我的例子中,正好是519326012)。
我不知道情况是否会一直如此。
有没有更好的方法来获得一个表的行数的精确计数?
简单地回答你的问题,没有。
如果你需要一个独立于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...