【问题标题】:Oracle Update on View extremly slow视图上的 Oracle 更新极慢
【发布时间】:2014-10-09 16:42:46
【问题描述】:

我有这个简单的 UPDATE 语句:

  UPDATE   v_my_view mv
     SET   mv.name   = 
              (SELECT   RTRIM(name)
                 FROM   v_another_view av
                WHERE av.KEY_ID = mv.KEY_ID)
   WHERE mv.VALID = 1;

此语句需要很长时间(20 秒),而同一视图上其他更复杂的更新需要不到 1 秒。一开始我以为是RTRIM功能,其实不是,不使用它还是像以前一样慢。

两个视图上的 SELECT 都非常快地返回记录。

视图上没有TRIGGER,但后面的桌子上有一个。但这不可能是瓶颈,因为即使我将所有 TRIGGER 代码注释掉,它的性能也一样慢。

有人有建议吗?

编辑:添加了缺少的 WHERE 子句 编辑:视图(或后面的表)每个只包含 8000 条记录,没有特殊的数据类型。

【问题讨论】:

  • 视图是如何定义的?即,v_my_view 和 v_another_view 的 DDL
  • 执行计划是什么?
  • @toddlermenot:这些视图是非常简单的选择,每个后面只有一个表。
  • @Wernfried:我不能在这里发布执行计划,因为它是我公司的代码和表名。在任何地方,每行的 COST 都非常低(30-33),而在顶部的总和中显示为 507214
  • 如果您直接对表编写相同的更新会发生什么? KEY_ID 字段是一对一的关系吗?您在查询计划中看到任何笛卡尔/叉积运算符吗?如果没有查询计划,我们只需要猜测并分而治之。您能否确认在基础表中,总记录(不包括任何 where 子句)约为 8000 条。即 8000 条不是预计会受到影响的记录,8000 条是表中实际记录的总数。

标签: sql oracle


【解决方案1】:

您正在更新整个视图而没有任何 WHERE 子句。

如果您有大量数据甚至索引,可能会减慢您的操作。

【讨论】:

  • 对不起,我忘了在我的帖子中添加 WHERE 子句,现在就添加。无论如何,完整的记录数是 appr。 8000 ……我猜太低了,不可能是瓶颈。
【解决方案2】:

v_my_view 的基础表中的列 name 是否有任何索引?如果是,请禁用它们并查看它是否会导致查询性能的任何改进。 正如 Nick.McDermaid 所说,没有执行计划和等待事件统计就很难说。最好的希望是某种形式的通灵调试。

【讨论】:

    【解决方案3】:
    merge --+ use_hash(MV,AV) no_merge(AV) no_merge(MV)
        into (select * from v_my_view MV where valid = 1)
    using v_another_view AV
    on MV.key_id = AV.key_id
    when matched then
        update
        set MV.name = rtrim(AV.name)
    ;
    

    虽然我不确定merge是否会进入内联视图,但您至少可以尝试一下(如果不起作用,请发表评论)。

    此外,最好将查询的执行计划与查询一起显示。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-08-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-21
      • 1970-01-01
      • 1970-01-01
      • 2018-08-12
      相关资源
      最近更新 更多