在更新中使用字段会大大降低查询速度

时间:2016-11-29 14:03:48

标签: sql oracle performance

我试图在oracle上采用层次结构,我遇到了严重的性能问题。 这是我的代码:

UPDATE {table} t1
SET (t1.{column2}) = (
    SELECT max(t2.{date}) FROM {table2} t2
    WHERE t2.{column} in(
        SELECT t3.{column}
        FROM {table3} t3
        START WITH t3.{columnt3} = 'blablabla'
        CONNECT BY t3.{columnt3} = PRIOR t3.{column}
        ))
WHERE t1.{column1} = 'blablabla'

此代码可在一秒钟内运行并运行。 现在,将第一个' blablabla' 替换为 t1。{column1} (这两个是等效的)会导致超过一分钟的执行时间。 代码看起来像这样:

UPDATE {table} t1
SET (t1.{column2}) = (
    SELECT max(t2.{date}) FROM {table2} t2
    WHERE t2.{column} in(
        SELECT t3.{column}
        FROM {table3} t3
        START WITH t3.{columnt3} = t1.{column1}
        CONNECT BY t3.{columnt3} = PRIOR t3.{column}
        ))
WHERE t1.{column1} = 'blablabla'

有人知道这个奇怪问题的原因吗?

修改 以下是上层(工作)查询的解释计划: first explain plan

这里是第二个(破碎的)查询的一个: second explain plan

正如您所看到的,运行时只是通过搜索t2(一个非常大的表)来爆炸。 但为什么会这样呢?这有什么原因吗?

编辑2:

也许原始代码可以帮助更多:

UPDATE tmp_obsolete t1
SET (liefertermin) = (
    SELECT max(versand_termin) FROM ropd7.pkvp
    WHERE artikel_nr in(
        SELECT pstp.artikel_nr
        FROM ropd7.pstp
        START WITH pstp.komponenten_art_nr =  'XX.XX.XX.XX.XX'
        CONNECT BY pstp.komponenten_art_nr = PRIOR pstp.artikel_nr
        ))
WHERE t1.artikel_nr = 'XX.XX.XX.XX.XX';


UPDATE tmp_obsolete t1
SET (liefertermin) = (
    SELECT max(versand_termin) FROM ropd7.pkvp
    WHERE artikel_nr in(
        SELECT pstp.artikel_nr
        FROM ropd7.pstp
        START WITH pstp.komponenten_art_nr =  t1.artikel_nr
        CONNECT BY pstp.komponenten_art_nr = PRIOR pstp.artikel_nr
        ))
WHERE t1.artikel_nr = 'XX.XX.XX.XX.XX';

2 个答案:

答案 0 :(得分:0)

重写查询帮助:

UPDATE {table} t1
SET (t1.{column2}) = (
    SELECT max(t2.{date})
      FROM {table2} t2
      JOIN {table3} t3
        ON t2.{column} = t3.{column}
     START WITH t3.{columnt3} = t1.{column1}
   CONNECT BY t3.{columnt3} = PRIOR t3.{column})
WHERE t1.{column1} = 'blablabl';

答案 1 :(得分:0)

我找不到使这个查询运行高效的好解决方案,所以我尝试使用一个简单的PL / SQL函数,它在给出参数时返回max(date)。 而且效果很好。 在400毫秒内完成约1000个条目。

感谢大家的帮助。