带子查询的Oracle更新 - performanceissue

时间:2013-10-31 09:27:25

标签: oracle join sql-update exists database-performance

我的oracle数据库中的更新语句有问题。 查询需要花费很多时间,临时表空间空间不足,但它提供了正确的数据。

我尝试将子查询转换为连接,但我无法弄清楚如何正确地执行此操作。 如果有人知道如何改进声明或如何将其转换为连接,我将非常感激。

        UPDATE table1 t1
        SET t1.inxdc = (SELECT sda_x
           FROM table2 t2
           WHERE t1.c1 = t2.c1
             AND t1.c2 = t2.c2
             AND t1.c3 = t2.c3
             AND t1.c4 = t2.c4
             AND t1.c5 = t2.c5
             AND t1.c6 = t2.c6
             AND t2.ident = 'K_SDA_W'
             AND rownum=1)
      WHERE EXISTS
          (SELECT 1
           FROM table2 t2
           WHERE t1.c1 = t2.c1
             AND t1.c2 = t2.c2
             AND t1.c3 = t2.c3
             AND t1.c4 = t2.c4
             AND t1.c5 = t2.c5
             AND t1.c6 = t2.c6
             AND t2.ident = 'K_SDA_W');

EDIT1: 表的一些信息

  • table1 PKs = c1,c2,c3,c4,c5,c6
  • table2 PKs = ident,c4,c5,c6和3个其他未在声明中提及的内容(c7,c8,c9)
  • index:仅限于table2 c1上的PK
  • table1数据:12466行
  • table2数据:194827行

EDIT2: 执行计划

    --------------------------------------------------------------
    | Id  | Operation                     | Name                 |
    --------------------------------------------------------------
    |   0 | UPDATE STATEMENT              |                      |
    |   1 |  UPDATE                       | table1               |
    |   2 |   NESTED LOOPS SEMI           |                      |
    |   3 |    TABLE ACCESS FULL          | table1               |
    |   4 |    TABLE ACCESS BY INDEX ROWID| table2               |
    |   5 |     INDEX RANGE SCAN          | t2.c1                |
    |   6 |   COUNT STOPKEY               |                      |
    |   7 |    TABLE ACCESS BY INDEX ROWID| table2               |
    |   8 |     INDEX RANGE SCAN          | t2.PK                |
    --------------------------------------------------------------

2 个答案:

答案 0 :(得分:0)

Table1中的行数非常少,只需在此特定情况下删除WHERE子句,并将NVL添加到子查询返回的值中:

UPDATE table1 t1
        SET t1.inxdc = NVL((SELECT sda_x
           FROM table2 t2
           WHERE t1.c1 = t2.c1
             AND t1.c2 = t2.c2
             AND t1.c3 = t2.c3
             AND t1.c4 = t2.c4
             AND t1.c5 = t2.c5
             AND t1.c6 = t2.c6
             AND t2.ident = 'K_SDA_W'
             AND rownum=1), t1.inxdc);

一般来说,您的更新应该很快,您是否检查了子查询的性能?检查子查询的table2上是否使用了索引(以及哪一个)(最好,向我们展示执行计划)。

答案 1 :(得分:0)

我认为表t2应该有一个关于c1,c2,c3,c4,c5,c6,缩进的索引 在这种情况下,t1的更新应该更快。