Oracle按行数(*)计算的行数与来自DBA_TABLES的NUM_ROWS行

时间:2013-01-02 16:42:16

标签: sql oracle count

看起来count(*)比NUM_ROWS慢。这个领域的专家可以对此有所了解。

2 个答案:

答案 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的其他两条信息。

  1. 在文档中,列名称旁边有一个星号,这引出了这个注释:

      

    标记为星号(*)的列仅在您收集时填充   使用ANALYZE语句或DBMS_STATS对表进行统计   封装

    这意味着除非您在表格上收集了统计信息,否则此列将不会包含任何数据。

  2. 使用默认estimate_percent或以100%估算收集的11g +统计数据将返回该时间点的准确数字。但是,在11g之前收集的统计信息,或者自定义estimate_percent小于100%的统计信息使用动态采样,可能不正确。如果你收集99.999%,可能会遗漏一行,这反过来意味着你得到的答案是错误的。

  3. 如果您的表从未更新,那么当然可以使用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的计算。表中的行数。