ALL_TABLES、count(*) 和 count(PRIMARY_KEY) 有什么区别?

What is the difference between ALL_TABLES, count(*) and count(PRIMARY_KEY)?

我正在使用 Oracle 数据库。这 3 个查询有什么区别?

select NUM_ROWS from ALL_TABLES where OWNER = 'ME' and TABLE_NAME = 'MY_TABLE'
select count(*) from ME.MY_TABLE
select count(PRIMARY_KEY) from ME.MY_TABLE

对于具有 8500 万行的大型 table,ALL_TABLES 查询需要 2 毫秒。 count(*)count(PRIMARY_KEY) 需要 5 秒。

附带问题:为什么 Oracle 数据库不对 count(*)count(PRIMARY_KEY) 使用 ALL_TABLES

从目录视图 ALL_TABLES 中查找列 NUM_ROWS 并不等同于实际计算 table 中的行数。它包含的信息基于上次收集有关 table 的统计信息(假设它们曾经是)。 The documentation states 只有当您使用 DBMS_STATS 包 收集有关 table 的统计信息时,它才会 填充。这在您 运行 查询(以及扩展)时是否准确,在很大程度上取决于您的统计信息收集策略以及 table 的修改方式。

另一方面,其他两个查询是等效的,它们会为您提供 table:

中的确切行数
select count(*) from ME.MY_TABLE
select count(PRIMARY_KEY) from ME.MY_TABLE

第一个查询写得更好,可能比第二个查询更有效,因为它实际上不需要检查每一行的列是否为空(尽管 Oracle 可能足够聪明,可以使用推断 PK 列永远不会为空的元数据) - 当您的 table 具有多列主键时它也有效。