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

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

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

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


当前回答

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

SHOW TABLE STATUS;

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

其他回答

如果SQL Server版本是2005/2008,您可以使用dmv来计算表中的行数:

-- Shows all user tables and row counts for the current database 
-- Remove is_ms_shipped = 0 check to include system objects 
-- i.index_id < 2 indicates clustered index (1) or hash table (0) 
SELECT o.name, 
 ddps.row_count 
FROM sys.indexes AS i 
 INNER JOIN sys.objects AS o ON i.OBJECT_ID = o.OBJECT_ID 
 INNER JOIN sys.dm_db_partition_stats AS ddps ON i.OBJECT_ID = ddps.OBJECT_ID 
 AND i.index_id = ddps.index_id 
WHERE i.index_id < 2 
 AND o.is_ms_shipped = 0 
ORDER BY o.NAME 

对于SQL Server 2000数据库引擎,sysindexes可以工作,但强烈建议避免在将来的SQL Server版本中使用它,因为它可能在不久的将来被删除。

示例代码摘自:如何快速轻松地获取表行计数

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

这取决于数据库。有些方法可以加速计数,例如通过跟踪索引中的行是活的还是死的,从而允许只扫描索引来提取行数。其他的则不是,因此需要访问整个表并逐个计算活动行。对于一张大桌子来说,这两种方式都很慢。

请注意,您通常可以通过使用查询优化工具、表统计信息等提取一个良好的估计。例如,在PostgreSQL的例子中,你可以从你的表中解析explain count(*)的输出,并得到一个相当好的行数估计。这就引出了你的第二个问题。

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

严重吗?:-)你真的是指一个有数十亿行的表的精确计数吗?你真的确定吗?: -)

如果您真的这样做了,您可以使用触发器跟踪总数,但如果这样做了,请注意并发性和死锁。

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

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

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

您可以尝试sp_spaceused (Transact-SQL)

显示行数、磁盘数 预留空间,磁盘占用空间 表、索引视图或服务 当前数据库中的代理队列, 或显示预留的磁盘空间 并被整个数据库使用。

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

SHOW TABLE STATUS;

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