<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 188,comments - 176,trackbacks - 0

    在大型的數據庫應用中,我們經常會有針對表與表之間的關鍵建進行字段更新,那么在這個時候,我們就不能寫簡單的update來實現更新操作,而要針對具體的數據量來進行批量的update,下面幾個例子是常用的SQL,將其做個對比,歡迎大家提出更好,更高效的SQL實現。


    數據庫:Oracle 9i  測試工具:PL/SQL

    定義2張測試表:T1,T2
    T1--大表 10000條 T1_FK_ID
    T2--小表 5000條  T2_PK_ID
    T1通過表中字段ID與T2的主鍵ID關聯


    模擬數據如下:

    --T2有5000條記錄
    create table T2 as select rownum id, a.* from all_objects a where 1=0;
    //T2表的字段和all_objects表字段類型以及默認值一致,但索引初始化了,需要重新設置

    --創建主鍵ID,向T2表copy數據
    alter table T2 add constraint T2_PK_ID primary key (ID);
    insert /*+ APPEND */ into T2 select rownum id, a.* from all_objects a where rownum<=5000;
     
    --T1有10000條記錄          
    create table T1 as select rownum sid, T2.* from T2 where 1=0;

    -- 創建外鍵ID,向T1表copy數據
    alter table T1 add constraint T1_FK_ID foreign key (ID) references t2 (ID);
    insert /*+ APPEND */ into T1 select rownum sid, T2.* from T2;
    insert /*+ APPEND */ into T1 select rownum sid, T2.* from T2;

    --更新Subobject_Name字段,初始為NULL
    update T2 set T2.Subobject_Name='StevenHuang'


    需求:我們希望能把T1表的Subobject_Name字段也全部更新成'StevenHuang',也就是說T1的10000條記錄都會得到更新,以下SQL語句均在PL/SQL命令窗口測試。

    方法一:
    寫PL/SQL,開cursor

    declare 
     l_varID 
    varchar2(20);
     l_varSubName 
    varchar2(30);
     
    cursor mycur is select T2.Id,T2.Subobject_Name from T2;
    begin 
     
    open mycur; 
     loop
          
    fetch mycur into l_varID,l_varSubName;
          
    exit when mycur %notfound;
          
    update T1 set T1.Subobject_Name = l_varSubName where T1.ID = l_varID;
     
    end loop;
     
    close mycur;
    end;

    ---耗時39.716s
    顯然這是最傳統的方法,如果數據量巨大的話(4000萬記),還會報”snapshot too old”錯誤退出,PL/SQL工具會掛掉

    方法二:
    用loop循環,分批update

    declare 
      i 
    number;
      j 
    number;
    begin
      i :
    = 1;
      j :
    = 0;
    select count(*into j from T1;
      loop
        
    exit when i > j;
        
    update T1 set T1.Subobject_Name = (select T2.Subobject_Name from T2 where T1.ID = T2.ID) where T1.ID >= i and T1.ID < 

    (i 
    + 1000);
        i :
    = i + 1000;
      
    end loop;
    end;

    --耗時0.656s,這里一共循環了10次,如果數據量巨大的話,雖然能夠完成任務,但是速度還是不能令人滿意。(例如我們將T1--大表增大到100000記錄 T2--小表增大到50000記錄,將耗時10.139s)

    方法三:
    --虛擬一張表來進行操作,在數據量大的情況下效率比方法二高很多.
       注:此語句下T1,T2表中必須有相應的主外建關聯,否則sql編譯不能通過.

    update (select T1.Subobject_Name A1,T2.Subobject_Name B1 from T1,T2 where T1.ID=T2.ID) set A1=B1; 

    --耗時3.234s (T1--大表增大到100000記錄 T2--小表增大到50000記錄)
    *以上所有操作都已經將分析執行計劃所需的時間排除在外

     
    轉:http://alex.bloghome.cn/posts/144915.html  
    注:以上傳載的文章中的SQL經過我測試,其結果和文章中的執行結果的時間是吻合的,有興趣的朋友可以自己測試一下。

    posted on 2007-12-28 20:11 cheng 閱讀(11469) 評論(0)  編輯  收藏 所屬分類: Oracle
    主站蜘蛛池模板: 亚洲三级在线免费观看| 一区国严二区亚洲三区| 亚洲精品中文字幕| 精品国产亚洲一区二区在线观看| 拍拍拍无挡视频免费观看1000| 亚洲大片免费观看| 免费国产成人高清在线观看麻豆| 中文在线观看免费网站| 亚洲制服丝袜精品久久| 国产成人免费a在线资源| 国产成人一区二区三区视频免费| 亚洲日韩精品无码专区加勒比 | 亚洲成av人片在线天堂无| 中文字幕中韩乱码亚洲大片 | 亚洲精品国自产拍在线观看| 色欲色香天天天综合网站免费| 久久综合亚洲色hezyo| 亚洲第一区香蕉_国产a| 日本视频免费在线| 91大神在线免费观看| 免费无码又爽又黄又刺激网站| 亚洲国产美女在线观看| 91麻豆精品国产自产在线观看亚洲| 两性刺激生活片免费视频| 国内精品99亚洲免费高清| 亚洲精品无码久久久久久| 久久久久亚洲精品美女| 免费成人黄色大片| 无码国产精品一区二区免费I6| 久久福利青草精品资源站免费| 亚洲欧美中文日韩视频| 亚洲精品福利网站| 国产亚洲婷婷香蕉久久精品| 免费一级毛片女人图片| 无码日韩人妻av一区免费| 午夜免费啪视频在线观看 | 国产网站在线免费观看| 很黄很黄的网站免费的| 国内精品久久久久影院免费| 欧亚一级毛片免费看| 亚洲国产无线乱码在线观看|