32

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

4

1 回答 1

31

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

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

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

于 2013-01-02T17:47:08.370 回答