现在有A、B两个表,字段基本一样,A表有200万行数据,B表有80万行数据,现在想通过B表的HPZL、HPHM两个字段和A表的HAOPZL、HAOPHM字段相同来更新A表的几个字段数据:
update A tt
     set (YEHMC,CHEPYS,CHANGPXH)=
        (select t.YHMC,t.CPYS,t.CPXH from B t where
        t.HPZL=tt.HAOPZL and t.HPHM=tt.HAOPHM) 
where exists(select 1 from  B t where  t.HPZL=tt.HAOPZL and t.HPHM=tt.HAOPHM )
用这个语句执行很长时间也执行不完,请问有没有更好、更快的update 语句?
谢谢!

解决方案 »

  1.   

    B表的HPZL、HPHM上建复合索引index1
    A表的HAOPZL、HAOPHM上复合索引index2
    update /*+ ordered use_nl(t, tt) */ t A tt
    set (YEHMC,CHEPYS,CHANGPXH)=
    (select t.YHMC,t.CPYS,t.CPXH from B t where
    t.HPZL=tt.HAOPZL and t.HPHM=tt.HAOPHM)
    where exists(select 1 from B t where t.HPZL=tt.HAOPZL and t.HPHM=tt.HAOPHM )
      

  2.   

    请问update /*+ ordered use_nl(t, tt) */ t A tt是什么意思?
      

  3.   

    这样
    update (select /*+ ordered use_nl(t,tt)*/
    tt.YHMC f1, tt.CPYS f2,tt.CPXH f3,t.YHMC ff1, t.CPYS ff2,t.CPXH ff3
    FROM B t,
    A tt
    WHERE t.HPZL=tt.HAOPZL and t.HPHM=tt.HAOPHM )
    SET f1=ff1, f2=ff2 , f3=ff3;
    就是让B表做驱动表和A表做nest loop连接.
      

  4.   

    你看一下执行计划,用EXISTS是全表扫描A表
    试试用游标更新数据
    declare
    type tb_1 is table of b.HPZL%type index by binary_integer;
    type tb_2 is table of b.HPHM%type index by binary_integer;
    type tb_3 is table of b.YHMC%type index by binary_integer;
    type tb_4 is table of b.CPYS%type index by binary_integer;
    type tb_5 is table of b.CPXH%type index by binary_integer;
    tab_HPZL tb_1;
    tab_HPHM tb_2;
    tab_YHMC tb_3;
    tab_CPYS tb_4;
    tab_CPXH tb_5;
    cursor cs is select HPZL, HPHM, YHMC, CPYS, CPXH from b;
    begin
    open cs;
    loop
    fetch cs bulk collect into tab_HPZL,tab_HPHM,tab_YHMC,tab_CPYS,tab_CPXH limit 5000;
    exit when cs%notfound;
    forall i in 1..tab_HPZL.count
    update a set YEHMC=tab_YHMC(i),
     CHEPYS=tab_CPYS(i),
     CHANGPXH=tab_CPXH(i)
    where HAOPZL=tab_HPZL(i) and HAOPHM=tab_HPHM(i);
    end loop;
    close cs;
    end;
      

  5.   

    请问 limit 5000是限定5000行还是每次限定5000行?
      

  6.   

    請問有沒有人執行成功這句話:
    update (select /*+ ordered use_nl(t,tt)*/
    tt.YHMC f1, tt.CPYS f2,tt.CPXH f3,t.YHMC ff1, t.CPYS ff2,t.CPXH ff3
    FROM B t,
    A tt
    WHERE t.HPZL=tt.HAOPZL and t.HPHM=tt.HAOPHM )
    SET f1=ff1, f2=ff2 , f3=ff3;
      

  7.   

    上面这个在有的oracle里可以,有的不可以,不知道为什么