【问题标题】:What is the difference between ALL_TABLES, count(*) and count(PRIMARY_KEY)?ALL_TABLES、count(*) 和 count(PRIMARY_KEY) 有什么区别?
【发布时间】:2020-11-10 00:52:18
【问题描述】:

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

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 万行的大表,ALL_TABLES 查询需要 2 毫秒。 count(*)count(PRIMARY_KEY) 需要 5 秒。

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

【问题讨论】:

    标签: sql database oracle count information-schema


    【解决方案1】:

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

    另一方面,另外两个查询是等价的,可以为您提供表中的确切行数:

    select count(*) from ME.MY_TABLE
    select count(PRIMARY_KEY) from ME.MY_TABLE
    

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

    【讨论】:

    • 如果已知是最新的,优化器能否使用ALL_TABLES?如果不是,那么当执行count(*) 查询时,查询是否可以更新ALL_TABLES?因此,第一次调用很慢,但其余的都很快。
    • @Nathan 虽然理论上 Oracle 可以添加这样的功能,但这可能需要大量的工作,并且会出现一些奇怪的行为或导致性能问题。您甚至可以使用快速可刷新的物化视图自己编写类似的功能。但是物化视图很难处理。
    猜你喜欢
    • 2011-02-22
    • 2020-03-02
    • 2014-06-09
    • 1970-01-01
    • 2010-09-08
    • 1970-01-01
    • 1970-01-01
    • 2015-03-03
    相关资源
    最近更新 更多