下面的查询可以重写吗?它需要花费很多时间来执行,并且有大量的数据抛出临时空间问题。我认为合并将改善性能。请提供建议并帮助我以更好的方式重写它
Update table1
Set Tgt_col ='2'
where col1 in (
SELECT ls.col1
FROM table1 ls
WHERE ls. Col2 ||ls. col3||ls.col22||To_Char(ls.time_col,'YYYYMMDD') IN (
SELECT o1. Col2||o1. col3||o1. col22||To_Char(o1. time_col,'YYYYMMDD')
FROM table1 o1
INNER JOIN table1 o2 ON o1. Col2 = o2. Col2
WHERE o1. col3<> o2. col3
AND Nvl(o1. col22, 'XX') = Nvl(o2. col22, 'XX')
AND To_Char(o1. time_col,'YYYYMMDD') = To_Char(o2. time_col,'YYYYMMDD')
AND o1.date_col = :A
AND o2. date_col = :A
AND o1.col10 = o2.col10
AND o1.col4 IN ('A','B','C')
AND o1.is_root=0 AND o1.is_leaf=1
AND o2. col4 IN ('A','B','C')
AND o2.is_root=0 AND o2.is_leaf=1
AND o1.col5 IN ('US','CA')
AND o2.col5 IN ('US','CA')
GROUP BY o1. Col2||o1. col3||o1. col22||To_Char(o1. time_col,'YYYYMMDD')
)
AND ls. col4 IN ('A','B','C')
AND ls.tgt_col IS NULL
AND ls. date_col = :A
AND ls.col5 IN ('US','CA')
AND ls.ID1 IN (SELECT ID1 FROM table2 F
WHERE F.col6 IN (SELECT col6 FROM table3
WHERE date_col =:A AND col7 = 1 )
AND F.col8 = '1')
);
答案 0 :(得分:0)
尝试以下代码,它应该更快:
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);
主要区别在于:
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
检查的行数。 / p>
代码内的注释中还有更多提示。
在提交前始终检查数据更改
希望我能帮上忙!
答案 1 :(得分:0)
在没有可用于测试的数据的情况下,我认为以下内容将比您当前的查询更快:
column
似乎您正在尝试在table1中查找col1值,其中每个col2,col3,time_col,col10和col22组合都具有多个不同的col3值,因此我使用了解析计数功能来找出该值。您可能会发现EXISTS比IN更好;您可以测试a)我的查询是否有效,b)用EXISTS替换IN是否对您的数据更快。