<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 閱讀(11466) 評論(0)  編輯  收藏 所屬分類: Oracle
    主站蜘蛛池模板: 国产精品免费一区二区三区| 日本免费一区尤物| 中文字幕免费在线| 亚洲精品免费在线| 女人18毛片水最多免费观看| 亚洲人成网77777亚洲色| 亚洲av无码不卡| 亚洲天天做日日做天天看 | 57PAO成人国产永久免费视频| 蜜桃视频在线观看免费网址入口| 国产女高清在线看免费观看| 亚洲理论片在线中文字幕| 五月天婷婷精品免费视频| 国产成人精品免费直播| 亚洲精品免费网站| 亚洲人成色77777在线观看大| 亚洲国产精品无码久久98| 日日操夜夜操免费视频| 国产亚洲精品无码成人| 国色精品va在线观看免费视频| 久久国产乱子伦精品免费不卡 | 国产成人亚洲综合无| 最近中文字幕mv免费高清在线| 亚洲色大成网站www永久一区| 国产精品免费看久久久香蕉| 色婷婷六月亚洲婷婷丁香| 精品视频免费在线| 麻豆国产入口在线观看免费 | 国产亚洲精品看片在线观看| 国产亚洲一卡2卡3卡4卡新区| 日本免费网站在线观看| 久久久久久亚洲av无码蜜芽| 日韩精品无码一区二区三区免费 | 久久亚洲中文字幕精品一区| 色五月五月丁香亚洲综合网| 亚洲AV天天做在线观看| 无码不卡亚洲成?人片| 日韩毛片免费在线观看| 无码免费午夜福利片在线| 国产免费爽爽视频在线观看| 亚洲精品视频免费|