如何加快这个更新sql语句

时间:2016-01-03 07:42:04

标签: sql oracle sql-update

我有这个更新,从视图(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 *

3 个答案:

答案 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以获得更好的效果。