看起来count(*)比NUM_ROWS慢。这个领域的专家可以对此有所了解。
答案 0 :(得分:20)
根据the documentation NUM_ROWS是“表格中的行数”,所以我可以看到这可能会让人感到困惑。然而,这两种方法之间存在重大差异。
此查询从系统视图中选择MY_TABLE中的行数。这是Oracle先前收集和存储的数据。
select num_rows from all_tables where table_name = 'MY_TABLE'
此查询计算MY_TABLE
中的当前行数select count(*) from my_table
根据定义,它们是不同的数据。您需要有关于NUM_ROWS的其他两条信息。
在文档中,列名称旁边有一个星号,这引出了这个注释:
标记为星号(*)的列仅在您收集时填充 使用ANALYZE语句或DBMS_STATS对表进行统计 封装
这意味着除非您在表格上收集了统计信息,否则此列将不会包含任何数据。
使用默认estimate_percent
或以100%估算收集的11g +统计数据将返回该时间点的准确数字。但是,在11g之前收集的统计信息,或者自定义estimate_percent
小于100%的统计信息使用动态采样,可能不正确。如果你收集99.999%,可能会遗漏一行,这反过来意味着你得到的答案是错误的。
如果您的表从未更新,那么当然可以使用ALL_TABLES.NUM_ROWS来查找表中的行数。 然而,并且它很大,但是如果任何进程从表中插入或删除行,它最多只是一个很好的近似值,并且取决于您的数据库是否自动收集统计信息可能是非常错误的。
一般来说,实际计算表中的行数而不是依赖系统表总是更好。
答案 1 :(得分:19)
1)从以下查询中获取NUM_ROWS意味着no.of rows值由 DBMS_STATS 更新。因此,它不包含表中的当前行数,而是在上次运行DBMS_STATS时计算的近似值。
SELECT table_name,
num_rows
FROM dba_tables
WHERE TABLE_NAME='NAME'
要更新DBA_TABLES
视图中的最新行计数值,请执行
exec dbms_stats.gather_schema_stats(ownname => 'NAME');
2)count(*)调用no的计算。表中的行数。