我有一个包含以下列的表:
val range_from range_to final_val
-2.12 -2 2 -2
-0.12 -2 2 -0.12
-0.12 -2 2 -0.12
1.51 -2 2 1.51
-1.29 -2 2 -1.29
2.23 -2 2 2
final_val是我需要使用以下条件计算的东西:
update table1
SET final_val= case
when val > range_to then range_to
when val < range_from then range_from
else VAL
END;
我的表格定义:
Name Null Type
---------- ---- ------
VAL NUMBER
RANGE_FROM NUMBER
RANGE_TO NUMBER
FINAL_VAL NUMBER
我桌上没有任何索引
以上查询需要很长时间才能执行。表大小为30GB。执行它需要超过16个小时。
有没有更好的方法来完成这项工作?
答案 0 :(得分:0)
尝试
update table1 SET final_val = val where val between range_from and range_to;
update table1 SET final_val = range_from where val < range_from;
update table1 SET final_val = range_to where val > range_to;
答案 1 :(得分:0)
答案 2 :(得分:0)
您正在更新表中的每条记录,并且Oracle确实遵守,即使不更改final_val
值,记录也会更新。因此,第一个措施是仅更新必须更新的记录,例如:
UPDATE table1
SET final_val = case when val > range_to then range_to
when val < range_from then range_from
else val
end
WHERE final_val <> case when val > range_to then range_to
when val < range_from then range_from
else val
end;
(如果列可以为空,则可能需要进行调整。例如:WHERE DECODE(final_val, case when ... end, 'equal', 'different') = 'different'
。)
然后你可以拥有一台可以执行并行操作的机器。所以提示可能有用:
UPDATE /*+parallel(table1,8)*/ table1
SET final_val = case when val > range_to then range_to
when val < range_from then range_from
else val
end
WHERE final_val <> case when val > range_to then range_to
when val < range_from then range_from
else val
end;
但是,您似乎希望final_val
始终是val
,range_from
和range_to
计算的值。在那种情况下,为什么要更新?写一个视图或使用虚拟列。