開発現場において、必ずどこかのタイミングで実施することになるのが性能試験。今回は性能試験時に便利な、大量のテストデータをクエリ一発で準備する方法をご紹介。
PLSQLとは?
PLSQL(Procedural Language/Structured Query Language)はOracleデータベースで使用されるプログラミング言語。SQLに手続き型言語要素を追加しており、複雑な処理や繰り返し処理を行うことが可能となっている。大規模なデータ処理を行う場合に特に便利な言語であり、現場でもテストデータの準備をするときによく使われる。というか、今のところテストデータ登録以外で利用されているのは見たことがない。自分だけ?
ダイレクトパスインサートの必要性
テストデータを大量に準備する際、通常のINSERT文では処理時間がかかってしまうという問題が発生する。まあ本番性能に関わる部分じゃないし、気長に待っても良いんだけど、100万件をINSERTするのに20分かかるのと、1分で終わるのでは流石にだいぶストレスが違う。実際の肌感でそのくらいの差は出るので、テストデータの登録時は、ダイレクトパスインサートを使用した方が無難だと思う。
SQLのサンプル
以下に、PLSQLを使用したダイレクトパスインサートのSQLサンプルを示す。
TBLレイアウトは面倒なのでここには書かないが、本文やコメントでなんとなく察することができると思う。
declare
TYPE t_data IS TABLE OF TEST_TABLE%ROWTYPE; -- テーブルのレコードを定義
v_data t_data := t_data(); -- データを格納する変数を初期化
begin
-- データを準備
-- データを v_data 変数に追加していく。件数分レコードを登録する。
for i in 1..1000 loop
v_data.extend; -- v_data 変数を拡張
-- カラムに値を設定
v_data(v_data.count).USER_ID := 'U1000'||LPAD(i, 9,'0'); -- PK項目は重複しないように連番を振って設定
v_data(v_data.count).INS_DATE := to_timestamp('2024/8/10 10:10:10','YYYY-MM-DD HH24:MI:SS.FF');
end loop;
-- データを挿入
forall i in 1..v_data.count
INSERT /*+ APPEND_VALUES */ INTO TEST_TABLE VALUES v_data(i);
commit; -- コミットを実行
end;
/
このサンプルでは、TEST_TABLEテーブルに対して、1000行のデータを一括挿入をするものであり、INSERT時に/*+ APPEND_VALUES */ヒントを付与することで、ダイレクトパスインサートを実現している。構文自体は難しいものではないので、このサンプルをベースにして別のTBL用に書き換えして貰えれば動くとはず。
ひとつ言うことがあるのであれば、こういうことをする際は、PK重複に気をつけなければいけないので、PK項目には連番を割り当てて一意にするようにすること。
また、複数のTBLを扱う場合は、t_data及びv_data変数をv_data_2とかで複製して設定してもらえればよい。もっとも個人的にはTBL毎にクエリを分けてしまった方がこの手のデータ登録時は混乱しづらい気がしているが。。
まとめ
PLSQLを使用してダイレクトパスインサートを行うことで、性能試験時に効率的に大量のテストデータを準備することが可能である。大きな理由がない限り、データ登録用のSQLもパフォーマンスを考慮しておいた方が、作業時のボトルネックが少なくて済む。