<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
    主站蜘蛛池模板: 91精品全国免费观看青青| 亚洲AV成人无码网天堂| 国产亚洲综合成人91精品| 亚洲国语精品自产拍在线观看 | 亚洲13又紧又嫩又水多| 中文字幕视频免费| 亚洲经典在线观看| 人妻视频一区二区三区免费| 亚洲国产日韩在线成人蜜芽| 一级做a毛片免费视频| 在线亚洲97se亚洲综合在线| 两个人的视频www免费| 久久精品夜色国产亚洲av| 99久9在线|免费| 日本亚洲国产一区二区三区| 黄色视屏在线免费播放| 最好免费观看韩国+日本| 亚洲国产aⅴ成人精品无吗| 日韩免费三级电影| 成在人线av无码免费高潮水| 亚洲国产一区在线| 毛片网站免费在线观看| 免费精品国自产拍在线播放| 国产亚洲精品a在线观看app| 亚洲综合免费视频| 亚洲AV成人片色在线观看高潮| 免费人成在线观看网站品爱网| 97se亚洲国产综合自在线| 亚洲精品国产免费| 亚洲AV无码一区二区三区牲色| 亚洲人午夜射精精品日韩| 久久久久久久99精品免费| 日本亚洲色大成网站www久久| 91老湿机福利免费体验| 中国亚洲呦女专区| 亚洲一区精品伊人久久伊人| 精品免费人成视频app| 免费福利在线观看| 亚洲依依成人精品| 亚洲日韩中文字幕日韩在线| 成人免费观看一区二区|