Попробуйте следующий код, он должен быть быстрее:
UPDATE table1
SET Tgt_col = '2'
WHERE EXISTS (SELECT 1
FROM table1 ls
JOIN table2 F
ON (f.ID1 = ls.ID1)
JOIN table3 t3
ON (t3.col6 = F.col6
-- IF :A is always inserted, you can remove if-null checkings for this date_col
AND ( (t3.date_col is null AND ls.date_col is null)
OR t3.date_col = ls.date_col
)
)
WHERE ls.col1 = table1.col1
AND EXISTS (SELECT 1
FROM table1 o1
JOIN table1 o2
ON (o1.Col2 = o2.Col2
AND o1.col10 = o2.col10
AND o1.is_root = o2.is_root
AND o1.is_leaf = o2.is_leaf
AND ( (o1.time_col is null AND o2.time_col is null)
OR o1.time_col = o2.time_col
)
AND ( (o1.col22 is null AND o2.col22 is null)
OR o1.col22 = o2.col22
)
-- IF :A is always inserted, you can remove if-null checkings for date_col
AND ( (o1.date_col is null AND o2.date_col is null)
OR o1.date_col = o2.date_col
)
AND o1.col3 != o2.col3)
WHERE (o1.Col2 = ls.Col2 OR (o1.Col2 is null AND ls.Col2 is null))
AND (o1.col3 = ls.col3 OR (o1.col3 is null AND ls.col3 is null))
AND (o1.col22 = ls.col22 OR (o1.col22 is null AND ls.col22 is null))
AND (o1.time_col = ls.time_col OR (o1.time_col is null AND ls.time_col is null))
-- IF :A is always inserted, you can remove if-null checkings for this date_col
AND (o1.date_col = ls.date_col OR (o1.date_col is null AND ls.date_col is null))
AND o1.is_root = 0
AND o1.is_leaf = 1
-- IF o1.col4 should be equal to o2.col4 THEN also add it inside `ON` and remove one of two from here
AND o1.col4 IN ('A', 'B', 'C')
AND o2.col4 IN ('A', 'B', 'C')
-- IF o1.col5 should be equal to o2.col5 THEN also add it inside `ON` and remove one of two from here
AND o1.col5 IN ('US', 'CA')
AND o2.col5 IN ('US', 'CA')
AND rownum = 1)
-- IF ls.col4 should be equal to col4 from inside the subquery THEN add it inside as, for example, for col22
AND ls.col4 IN ('A', 'B', 'C')
AND ls.tgt_col IS NULL
AND ls.date_col = :A
-- IF ls.col5 should be equal to col5 from inside the subquery THEN add it inside as, for example, for col22
AND ls.col5 IN ('US', 'CA')
AND F.col8 = '1'
AND t3.col7 = 1
AND rownum = 1);
Основные различия:
- Удаление конкатенации и добавление ее по сравнению сзначения в выражении where
- Использование
EXISTS
с rownum
вместо IN
- Использование
JOIN
вместо IN
для table2 F
и table3
сравнения
Если col1
является уникальным ключом, запишите все проверки ls table
во внешнем запросе (ls.col4 IN ('A', 'B', 'C') AND ls.tgt_col IS NULL AND ls.date_col = :A AND ls.col5 IN ('US', 'CA')
), чтобы уменьшить количество строк, проходящих проверку EXISTS
.
В коде есть и другие советы в комментариях.
Всегда проверяйте изменения данных перед фиксацией
Надеюсь, я помог!