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

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

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

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


当前回答

您可以尝试sp_spaceused (Transact-SQL)

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

其他回答

我远不及其他回答问题的专家,但我在从表中选择随机行(不太相关)的过程中遇到了问题,但我需要知道我的参考表中的行数来计算随机索引。使用传统的Count(*)或Count(1)可以工作,但我偶尔需要2秒才能运行查询。所以相反(对于我的表命名为'tbl_HighOrder')我使用:

Declare @max int

Select @max = Row_Count
From sys.dm_db_partition_stats
Where Object_Name(Object_Id) = 'tbl_HighOrder'

它工作得很好,在Management Studio中的查询时间为零。

如果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(1) FROM TableLarge 

花了37秒

SELECT COUNT_BIG(1) FROM TableLarge

只需要4秒钟。

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

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

如果你需要一个独立于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...

在某列上放一个索引。这应该允许优化器执行索引块的完整扫描,而不是对表的完整扫描。这将大大降低你的IO成本。看看前后的执行计划。然后用两种方法测量挂钟的时间。