我有这个更新,从视图(upd_g307)获取数据,计算每个系列中的成员并将其放入另一个表s_general 这是更新
Update s_general
Set g307 = (select upd_g307.county
from upd_g307
where upd_g307.id_section = s_general.Id_section
and upd_g307.rec_no = s_general. Rec_no
and upd_g307.f306 = s_general.F306)
Where
g307 is null
and id_section between 14000 and 15000
此查询需要花费很长时间才能运行半个小时甚至更长时间!我该怎么做才能让它更快? 我正在使用oracle sql *
答案 0 :(得分:2)
当重写为MERGE语句时,这种语句通常更快:
merge into s_general
using (
select county, id_section, rec_no, f306
from upd_g307
where id_section between 14000 and 15000
) t on (t.id_section = s_general.Id_section and t.rec_no = s_general.rec_no and t.f306 = s_general.F306)
when matched then update
set g307 = upd_g307.county
where g307 is null;
upd_g307 (id_section, rec_no, f306, county)
上的索引可能有所帮助,以及s_general (id_section, rec_no, f306)
上的索引。
答案 1 :(得分:0)
您可以在Oracle中使用updatable join视图,无论如何我都会看看连接的性能,因为IMO是您可能期望从更新中获得的经过时间的下限。
语法如下:
UPDATE (
SELECT s_general.g307, upd_g307.county
FROM s_general
JOIN upd_g307 on upd_g307.id_section = s_general.Id_section
and upd_g307.rec_no = s_general. Rec_no
and upd_g307.f306 = s_general.F306
and s_general.g307 is null
and s_general.id_section between 14000 and 15000
)
set g307 = county
不幸的是,你很有可能获得
ORA-01779: cannot modify a column which maps to a non key-preserved table
如果找不到视图upd_g307
key-preserved
您可能会或可能不会解决它在视图的源表上定义PK约束。作为最后的手段,定义一个临时表(可能是GGT),在连接键上使用PK约束,而不是视图。
-- same DDL as upd_g307
CREATE GLOBAL TEMPORARY TABLE upd_g307_gtt
(Id_section number,
Rec_no number,
F306 number,
g307 number,
county number)
;
-- default -> on commit delete
ALTER TABLE upd_g307_gtt
ADD CONSTRAINT pk_upd_g307_gtt
PRIMARY KEY (id_section, Rec_no, F306);
insert into upd_g307_gtt
select * from upd_g307;
UPDATE (
SELECT s_general.g307, upd_g307_gtt.county
FROM s_general
JOIN upd_g307_gtt on upd_g307_gtt.id_section = s_general.Id_section
and upd_g307_gtt.rec_no = s_general. Rec_no
and upd_g307_gtt.f306 = s_general.F306
and s_general.g307 is null
and s_general.id_section between 14000 and 15000
)
set g307 = county
;
答案 2 :(得分:-1)
对于MS SQL:
DECLARE @TEMP VARCHAR(50)
------------------------------------
select @TEMP=upd_g307.county
from upd_g307
where upd_g307.id_section=s_general. Id_section
and upd_g307.rec_no=s_general. Rec_no;
------------------------------------------
Update s_general
SET g307=@TEMP
Where g307 is null and id_section between 14000 and 15000
或使用MERGE
以获得更好的效果。