Oracle SQL相关更新性能较低

时间:2013-11-19 09:44:19

标签: sql oracle correlated-subquery

我必须使用来自其他两个表的数据更新表(table3)。 这两个表(table1,table2)都描述了单个对象,因此table1.id等于该单个对象的table2.id。 表3是该对象的多对多映射表,另一个在此处不重要。在该映射表中,我需要从table1和table2中放入一些数据。

我正在尝试使用相关查询更新table3,但是需要很长时间才能完成。我在~500.000条记录组上运行了这个查询,它现在运行了一个多小时。

我在这里做错了吗?

UPDATE table3 t3
SET (t3.some_value1, t3.other_value1, t3.some_value2, t3.other_value2) =
(   SELECT t1.some_value1, t1.other_value1, t2.some_value2, t2.other_value2
    FROM table1 t1 JOIN table2 t2 ON t1.id = t2.id
    WHERE t3.fk = t1.id)
WHERE EXISTS (SELECT 1 FROM table1 t1 JOIN table2 t2 ON t1.id = t2.id WHERE t3.fk = t1.id);


SELECT * FROM table3;

SQL Fiddle

2 个答案:

答案 0 :(得分:1)

使用此:

UPDATE
      (SELECT
            T3.SOME_VALUE1 TARGET1,
            T3.OTHER_VALUE1 TARGET2,
            T3.SOME_VALUE2 TARGET3,
            T3.OTHER_VALUE2 TARGET4,
            T1.SOME_VALUE1 SOURCE1,
            T1.OTHER_VALUE1 SOURCE2,
            T2.SOME_VALUE2 SOURCE3,
            T2.OTHER_VALUE2 SOURCE4
       FROM
            TABLE1 T1
            JOIN TABLE2 T2
                ON T1.ID = T2.ID
            JOIN T3
                ON T3.FK = T1.ID)
SET
      TARGET1   = SOURCE1,
      TARGET2   = SOURCE2,
      TARGET3   = SOURCE3,
      TARGET4   = SOURCE4;

如果您面对ORA-01779 cannot modify a column which maps to a non key-preserved table,请尝试使用UPDATE /*+ BYPASS_UJCV */或在T1.ID,T2.ID,T3.FK上添加唯一索引

答案 1 :(得分:0)

@SriniV提供的答案使用称为$("#turnOffAll").click(function(){ var filterId=$('#filterId').val(); console.log('clicked on filter'+filterId); }); 的技术。在更高版本的Oracle中,可以用Updatable Join View代替:

MERGE INTO t3
USING (
    SELECT t1.id 
        t1.some_value1, 
        t1.other_value1, 
        t2.some_value2, 
        t2.other_value2
    FROM table1 t1 
        JOIN table2 t2 ON t1.id = t2.id
    WHERE 1=1
        AND t3.fk = t1.id
) a ON (
    t3.fk = a.id
)
WHEN MATCHED THEN UPDATE
    SET t3.some_value = a.some_value,
        t3.other_value1 = a.other_value1
        t3.some_value2 = a.some_value2
        t3.other_value2 = a.other_value2