【问题标题】:Oracle row count of table by count(*) vs NUM_ROWS from DBA_TABLES通过 count(*) 与 DBA_TABLES 中的 NUM_ROWS 计算表的 Oracle 行数
【发布时间】:2012-12-17 00:53:56
【问题描述】:

看起来 count(*) 比 NUM_ROWS 慢。这方面的专家能否对此有所了解。

【问题讨论】:

  • num_rows 是一个可能不是最新的统计数据。如果您需要实际计数,那么您应该使用计数(*)来对抗表格本身
  • @Paul Tomblin - 有一个广泛的 Ask Tom 讨论来揭穿这个想法。是一样的。
  • 我不认为 count(1) 和从 NUM_ROWS 获取计数是一样的
  • 不需要@FrostyZ,OP 正在询问从系统视图中选择单行和计算表中的行数之间的区别......

标签: sql oracle count


【解决方案1】:

根据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%,可能会漏掉一行,这反过来意味着你得到的答案是不正确的。

如果您的表从不更新,那么当然可以使用 ALL_TABLES.NUM_ROWS 来找出表中的行数。 然而,但这是一个很大的问题,如果任何进程从您的表中插入或删除行,它充其量只是一个很好的近似值,并且取决于您的数据库是否自动收集统计数据可能是非常错误的。

一般来说,实际计算表中的行数总是比依赖系统表更好。

【讨论】:

    猜你喜欢
    • 2021-02-18
    • 2011-07-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-12
    • 1970-01-01
    • 1970-01-01
    • 2012-07-06
    • 1970-01-01
    相关资源
    最近更新 更多