我曾经读过一些文章,说当表有很多行和很多列时,SELECT COUNT(*) FROM TABLE_NAME将会很慢。
我有一个可能包含数十亿行的表(它大约有15列)。有没有更好的方法来获得一个表的行数的精确计数?
在回答之前请考虑以下问题:
我正在寻找一个数据库供应商
独立的解决方案。如果是也可以
涵盖MySQL, Oracle, MS SQL Server。
但如果真的没有数据库
供应商独立的解决方案,然后我
会接受不同的解决方案吗
针对不同的数据库供应商。
我不能使用任何外部工具
这样做。我主要是在找一个
基于SQL的解决方案。
我不能规范化我的数据库设计
任何进一步的。它已经在3NF中,而且
很多代码已经写好了
围绕它。
我找到了一篇很好的文章:SQL Server-HOW-TO:快速从martijnh1检索表的准确行数,它很好地概述了每个场景。
我需要在需要根据特定条件提供计数的地方进行扩展,当我计算出这一部分时,我会进一步更新这个答案。
与此同时,以下是文章中的细节:
方法1:
查询:
SELECT COUNT(*) FROM Transactions
评论:
执行全表扫描。在大桌子上慢点。
方法2:
查询:
SELECT CONVERT(bigint, rows)
FROM sysindexes
WHERE id = OBJECT_ID('Transactions')
AND indid < 2
评论:
快速检索行数的方法。取决于统计数据,不准确。
运行DBCC UPDATEUSAGE(数据库)WITH COUNT_ROWS,这对于大型表可能会花费大量时间。
方法3:
查询:
SELECT CAST(p.rows AS float)
FROM sys.tables AS tbl
INNER JOIN sys.indexes AS idx ON idx.object_id = tbl.object_id and
idx.index_id < 2
INNER JOIN sys.partitions AS p ON p.object_id=CAST(tbl.object_id AS int)
AND p.index_id=idx.index_id
WHERE ((tbl.name=N'Transactions'
AND SCHEMA_NAME(tbl.schema_id)='dbo'))
评论:
SQL管理工作室计算行数的方法(查看表属性、存储、行数)。非常快,但仍然是大概的行数。
方法4:
查询:
SELECT SUM (row_count)
FROM sys.dm_db_partition_stats
WHERE object_id=OBJECT_ID('Transactions')
AND (index_id=0 or index_id=1);
评论:
操作快(虽然不如方法二快),同样重要的是,可靠。
简单的回答是:
数据库供应商独立的解决方案=使用标准= COUNT(*)
有近似的SQL Server解决方案,但不要使用COUNT(*) =超出范围
注:
COUNT(1) = COUNT(*) = COUNT(主键)以防万一
编辑:
SQL Server示例(14亿行,12列)
SELECT COUNT(*) FROM MyBigtable WITH (NOLOCK)
-- NOLOCK here is for me only to let me test for this answer: no more, no less
1运行,5分46分钟,计数= 1,401,659,700
--Note, sp_spaceused uses this DMV
SELECT
Total_Rows= SUM(st.row_count)
FROM
sys.dm_db_partition_stats st
WHERE
object_name(object_id) = 'MyBigtable' AND (index_id < 2)
2次,都在1秒内,计数= 1,401,659,670
第二个有较少的rows =错误。相同或更多取决于写入(这里的删除是按小时计算的)