プログラム研究所
ソフトウェア開発やプログラミングの豆知識を載せています。
04 | 2018/05 | 06
S M T W T F S
- - 1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31 - -

スポンサーサイト
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

INSERTのBULK化による高速化
PL/SQLでまとまったデータをテーブルにINSERTするようなルーチンを作る時にINSERTBULK化すると高速に処理できます。高速化できるのはSQLエンジンとPL/SQLエンジンのコンテキストスイッチを極小化するためです。出力テーブルに関し下記のようなルーチンを適当なスコープに作成して活用することができます。

内部のデータ構造

{target}の部分は出力先のテーブル名に置換してください。

type tab{target} is table of {target}%rowtype index by pls_integer; bulk_buf tab{target}; bulk_idx pls_integer; bulk_siz constant pls_integer := 500; /* バッファ既定サイズ;最適値はテストで決まる */

内部バッファのサイズ bulk_siz の最適値は実行環境で速度を実測した上で決めてください。一般にサイズが小さいうちはリニアに速度が向上しますが、ある大きさ以上になると頭打ちになります。

プロシージャ定義

{target}の部分は出力先のテーブル名に置換してください。

err_buf{target} exception; procedure open{target} is begin --バッファを空にする bulk_buf.delete; bulk_idx := 0; exception when others then raise err_buf{target}; end open{target}; procedure close{target} is begin if bulk_idx > 0 then --バッファのデータをテーブルに転送 forall i in 1..bulk_idx insert into {target} values bulk_buf(i); commit; --バッファを空にする bulk_buf.delete; bulk_idx := 0; end if; exception when others then rollback; raise err_buf{target}; end close{target}; procedure write{target}(rec {target}%rowtype) is begin --バッファに追加 bulk_idx := bulk_idx + 1; bulk_buf(bulk_idx) := buf; --バッファが一杯になったらテーブルに転送 if bulk_idx >= bulk_siz then close{target}; end if; exception when others then raise err_buf{target}; end write{target};

サンプル

{target}の部分は出力先のテーブル名に置換してください。

アプリケーションでは1レコードずつ転送しているようにコーディングしますが、実際は、openで準備されたバッファにwriteで書き込みします。writeはバッファがいっぱいになると、テーブルに一括で転送を行います。最後にアプリケーションはバッファに残っておりテーブルに転送されていないデータをフラッシュするためにcloseを呼びます。

declare cursor c1 select col1,col2,... from {source} where ....; rec {target}%rowtype; begin /* 前処理 */ open{target}; /* ソースデータの読み込み */ for r1 in c1 loop /* ターゲットへの書き込みレコードを構成 */ rec := null; rec.col1 := r1.col1; rec.col2 := r1.col2; : /* 転送 */ write{target}(rec); end loop; /* 後処理 */ close{target} /* 例外処理 */ exception when err_buf{target} then dbms_output.put_line('処理失敗...'); end;
スポンサーサイト

テーマ:プログラミング - ジャンル:コンピュータ

コメント
要望
bulk bind でデータ転送したいテーブルが複数ある時に、同じようなコーディングをすることになり面倒です。対象のテーブルを動的に指定できるようなライブラリにならないものでしょうかね。。。
[2011/07/13 12:42] URL | mango #amXlFcx2 [ 編集 ]

Re: 要望
> bulk bind でデータ転送したいテーブルが複数ある時に、同じようなコーディングをすることになり面倒です。対象のテーブルを動的に指定できるようなライブラリにならないものでしょうかね。。。

同感です。動的なSQLにする必要があるかな。。。研究してみますね。

[2011/07/16 21:13] URL | Prog.Labo #62mf5KEU [ 編集 ]


コメントの投稿














管理者にだけ表示を許可する


トラックバック
トラックバック URL
http://proglabo.blog.fc2.com/tb.php/7-b1d34575
この記事にトラックバックする(FC2ブログユーザー)

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。