Decode360's Blog

          業精于勤而荒于嬉 QQ:150355677 MSN:decode360@hotmail.com

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 ::  :: 管理 ::
            302 隨筆 :: 26 文章 :: 82 評論 :: 0 Trackbacks
          <2009年4月>
          2930311234
          567891011
          12131415161718
          19202122232425
          262728293012
          3456789

          公告

          常用鏈接

          隨筆分類(299)

          隨筆檔案(299)

          文章分類(26)

          新聞分類(24)

          收藏夾(5)

          Blog列表

          IT網站

          My Link

          最新隨筆

          最新評論

          ??? Oracle可以將Update和Insert操作合并為一個MERGE操作。第一可以更加方便操作、簡化邏輯,第二在Oracle的內部進行了效率的優化。
          ?
          ??? 在下面的舉例可以看出,如果使用PLSQL中的exception來判斷是UPDATE還是INSERT,效率是及其低下的。而在SQL層級使用MERGE或者手動分兩步進行INSERT|UPDATE,效率相差無幾。使用MERGE的優勢是邏輯簡單,一般無特使要求均以使用MERGE函數為佳。而使用兩步的優點是可以返回有多少記錄是UPDATE多少記錄是INSERT的,還可以精確反映在哪一步發生錯誤。所以后兩種方法各有優勢,第一種方法是需要極力避免的。
          ?
          ?
          SQL> create table t1 as select object_id, object_name from all_objects;
          ?
          Table created.
          ?
          SQL> alter table t1 add constraint t1_pk primary key(object_id);
          ?
          Table altered.
          ?
          SQL> create table t2 as select * from t1;
          ?
          Table created.
          ?
          SQL> alter table t2 add constraint t2_pk primary key(object_id);
          ?
          Table altered.
          ?
          SQL>
          SQL> analyze table t1 compute statistics
          ? 2? for table
          ? 3? for all indexes
          ? 4? for all indexed columns;
          ?
          Table analyzed.
          ?
          SQL>
          SQL> analyze table t2 compute statistics
          ? 2? for table
          ? 3? for all indexes
          ? 4? for all indexed columns;
          ?
          Table analyzed.
          ?
          SQL>
          SQL> set timing on
          SQL> declare
          ? 2????????? l_icnt number := 0;
          ? 3????????? l_ucnt number := 0;
          ? 4? begin
          ? 5????? for x in ( select * from t1 )
          ? 6????? loop
          ? 7????????? begin
          ? 8????????????? insert into t2 ( object_id, object_name ) values ( x.object_id, x.object_name );
          ? 9????????????????????????? l_icnt := l_icnt+1;
          ?10????????? exception
          ?11????????????? when dup_val_on_index then
          ?12????????????????? update t2 set object_name = x.object_name where object_id = x.object_id;
          ?13??????????????????????????l_ucnt := l_ucnt+1;
          ?14????????? end;
          ?15????? end loop;
          ?16????????? dbms_output.put_line( 'Inserted ' || l_icnt );
          ?17????????? dbms_output.put_line( 'Updated? ' || l_ucnt );
          ?18? end;
          ?19? /
          Inserted 0
          Updated? 29317
          ?
          PL/SQL procedure successfully completed.
          ?
          Elapsed: 00:01:04.07
          SQL> rollback;
          ?
          Rollback complete.
          ?
          Elapsed: 00:00:00.86
          SQL>
          SQL> begin
          ? 2????? update ( select t1.object_name t1_oname, t2.object_name t2_oname
          ? 3???????????????? from t1, t2
          ? 4??????????????? where t1.object_id = t2.object_id )
          ? 5???????? set t1_oname = t2_oname;
          ? 6
          ? 7????????? dbms_output.put_line( 'Updated? ' || sql%rowcount );
          ? 8
          ? 9???????? insert into t1
          ?10????? select * from t2 where t2.object_id not in ( select object_id from t1 );
          ?11
          ?12????????? dbms_output.put_line( 'Inserted ' || sql%rowcount );
          ?13? end;
          ?14? /
          Updated? 29317
          Inserted 0
          ?
          PL/SQL procedure successfully completed.
          ?
          Elapsed: 00:00:02.44
          SQL> rollback;
          ?
          Rollback complete.
          ?
          Elapsed: 00:00:01.07
          SQL>
          SQL> merge into t1
          ? 2? using t2
          ? 3? on ( t2.object_id = t1.object_id )
          ? 4? when matched then
          ? 5???? update set t1.object_name = t2.object_name
          ? 6? when not matched then
          ? 7????? insert (object_id, object_name) values( t2.object_id, t2.object_name);
          ?
          29317 rows merged.
          ?
          Elapsed: 00:00:02.87
          SQL>
          SQL> rollback;
          ?
          Rollback complete.
          ?
          Elapsed: 00:00:01.08
          ?
          ?
          ??? 另外,Tom還建議:除非是特殊情況,否則不要使用分段提交。因為這樣會破壞事務的一致性,而且會影響整體的性能。
          ??? 如果一定要使用批量提交(例如undo表空間太小且不可增加時),加入以下代碼即可(只能用cursor來update)
          ?
          begin
          ??? ...
          for?xc1 in c loop
          ??? commit_point:=commit_point+1;
          ??? if commit_point > 10000 then
          ??? commit;
          ??? commit_point:=0;
          ??? end if;
          ??? begin
          ??????? ...
          ??? end;
          end loop;
          ??? ...
          end;
          ?
          ?
          ?
          ?




          -The End-

          posted on 2009-04-01 21:23 decode360-3 閱讀(269) 評論(0)  編輯  收藏 所屬分類: SQL Dev
          主站蜘蛛池模板: 凌源市| 孟连| 湟源县| 芮城县| 沅陵县| 鄯善县| 乐陵市| 枣强县| 获嘉县| 新河县| 云和县| 安图县| 淮滨县| 新密市| 太湖县| 阳原县| 阿合奇县| 齐齐哈尔市| 拉萨市| 霸州市| 赣榆县| 黄大仙区| 渭源县| 永兴县| 侯马市| 龙川县| 怀宁县| 镇巴县| 太和县| 乐至县| 丰顺县| 化隆| 友谊县| 汉源县| 阿克陶县| 五原县| 芜湖县| 梁山县| 平果县| 惠水县| 连南|