【问题标题】:Why does my count(*) query time out but the inline view whose records it is counting does not?为什么我的 count(*) 查询超时,但它正在计算记录的内联视图却没有?
【发布时间】:2010-05-11 15:36:47
【问题描述】:

无法弄清楚这一点...当我执行选择查询时,它显示解释计划成本约为 4500 并且需要约 3 秒才能返回。当我将该查询(没有更改)包装在:

select count(*) from (
 /*query here*/
)

超时。现在是 5 分钟,现在开始计时。

我在 SQL Developer 和 Aqua Data Studio 中尝试过——结果相同。

【问题讨论】:

    标签: sql oracle count


    【解决方案1】:

    在执行COUNT(*) 时,优化器将其目标更改为ALL_ROWS,这可能会严重影响计划。

    您能在此处发布您的查询吗?

    【讨论】:

    • 我没有意识到这会影响计划......它确实令人惊讶,因为我希望原始计划是它确定的最有效和知道计数的唯一方法该结果集是首先执行嵌套查询。
    • @RenderIn:您的优化器目标似乎设置为FIRST_ROWS(这意味着尽快返回第一条记录,即使整体查询时间会增加)。但是,Oracle 的优化器不是很聪明,经常会被混淆。顺便说一句,当您在 SQL Developer 中运行查询时,您是否曾经按“获取全部”以获得 all 结果?
    • 不确定“获取全部”的确切位置,但是当我执行脚本 (F5) 而不是运行语句 (F9) 时,它将返回最多 5000 行而不是默认的 50使用 F9 时。一次返回 5k 行大约需要 11 秒,总共有 9520 条记录。
    • @RenderIn:您能否在此处发布您的查询和两个计划?
    【解决方案2】:

    可能是优化器不“知道”您的表的真实样子。

    尝试分析查询中使用的表:

    EXEC dbms_stats.gather_table_stats(
        ownname => <owner-name>,
        tabname => <table-name>,
        cascade => TRUE );
    

    【讨论】:

      【解决方案3】:

      如果不查看整个查询,就无法判断,但对于初学者,我会尝试查看 explain plan 输出。

      【讨论】:

        【解决方案4】:

        COUNT(*) 操作计算由其下的执行计划分支提供给它的所有行。这意味着优化器会等待ALL_ROWS 在完成其执行之前返回,这可能会严重影响您的查询计划。

        【讨论】:

          【解决方案5】:

          您想为您的count 查询使用定义的选择,优化的不知道它将计算哪些表。

          另外,不要使用count(*),因为它将计算所有列,只需使用count(COLUMN_NAME)

          【讨论】:

          【解决方案6】:

          如果您尝试这样做:

          选择计数(*)
          来自(选择...来自...);

          然后你应该尝试指定你希望在哪个字段上执行计数,例如:

          选择 COUNT(我的字段)
          FROM(从 MYTABLE 中选择任何、任何、任何);

          你指的是这个吗?

          【讨论】:

          • 这可以改变查询语义:它只会返回myfield IS NOT NULL的记录数,如果myfield不能是NULL,则不会有性能优势。
          猜你喜欢
          • 1970-01-01
          • 2013-08-16
          • 2021-10-01
          • 2019-04-06
          • 1970-01-01
          • 2017-05-29
          • 1970-01-01
          • 1970-01-01
          • 2015-05-05
          相关资源
          最近更新 更多