配列 DML コマンドのパフォーマンス(FireDAC)
コマンドの操作(FireDAC) への移動
このトピックでは、FireDAC でサポートしている配列 DML 機能のパフォーマンスの高さについて説明します。 最初のこのトピックでは、簡単な例を使って、ほんの数行のコードを書くだけで 1 秒間に何千行ものレコードを挿入する方法を示します。
はじめに
FireDAC には配列 DML コマンドをデータベース サーバーごとに実装したものがすべてカプセル化されているため、ユーザーはサーバーの種類に関わらず同じコードを使用することができます。 その結果のパフォーマンスは、サーバー実装によって異なります。 主に Oracle や Microsoft SQL Server や IBM DB2 は配列 DML を非常に強力にサポートしているため、結果のパフォーマンスは目に見えて向上します。
まずサンプル コードを使用して、アプリケーションやネットワークのパフォーマンスを向上できる可能性を感じてみてください。
テスト環境の準備方法
以下の例では、FireDAC のサンプル データベース環境を使用します。 このデータベースのインストール方法の詳細は、FireDAC デモ データベースを確認してください。 デモ プロジェクトはサンプル ディレクトリに含まれています。
- このチュートリアルで使用するコード: FireDAC\Samples\Comp Layer\TFDQuery\ExecSQL\AD03-ArrayDML
- 基本のコード例: FireDAC\Samples\Comp Layer\TFDQuery\ExecSQL\Batch
配列 DML コマンドの主な要素
INSERT、UPDATE、DELETE など、パラメータを取るコマンドを N 回(通常は 1 つのレコードに対して 1 コマンド)実行しなければならない "使用例" を考えてください。 この場合、1 組の入力パラメータごとに SQL コマンドの実行が要求され、そのたびにクライアントとサーバーの間でパラメータ群が転送されるため、ネットワークとクライアントとサーバーに高い負荷がかかります。
配列 DML を使用すると、一度の転送で 1 組だけではなく N 組のデータ群を送ることができます。 次の例を見てください。
FDQuery1.SQL.Text:= 'insert into ADQA_Batch_test (tint, tstring) values(:f1, :f2)';
配列 DML コマンドを使用することで、コードを劇的に高速化できます。 配列 DML コマンドでは、1 組だけではなく N 組のパラメータ群が転送されます。
FDQuery1.Params.ArraySize := 100;
...
for i := 0 to FDQuery1.Params.ArraySize do begin
FDQuery1.Params[0].AsIntegers[i] := i;
FDQuery1.Params[1].AsStrings[i] := 'Test' + IntToStr(i);
end;
FDQuery1.Execute(FDQuery1.Params.ArraySize);
クエリの Params プロパティは、1 次元配列ではなく 2 次元配列になっているため、N 組のパラメータ値を格納してサーバーに送信することができます。
詳細は、「配列 DML」を参照してください。
使い方のヒント
- パラメータを使用する任意の SQL コマンド(INSERT、UPDATE、DELETE など)で使用できます。
- エラー処理はレコード レベルでサポートされています。これについては別のトピックで説明します。
- FireDAC では、さまざまな種類のサーバーの配列 DML が統一されています(API を詳しく調べる必要がありません)。
配列 DML をテスト実行したときの典型的な結果
付属のテスト コードを使用して、自分自身の環境で実験をすることができます。
テスト例の結果は、ホストやネットワークのパフォーマンスによって大きく異なります。 少し古いラップトップでローカルの Oracle を動かしている場合でも、典型的な結果は、次のスクリーンショットに見られるように、1 秒あたり 100,000 レコード以上になります。
配列 DML の配列サイズが大きくなると、パフォーマンスは高くなります(この例で最大 2000 倍)。
パフォーマンスのヒント
配列 DML コマンドのパフォーマンスは以下のような条件によって変わります。
- ネットワークの速度が遅い場合には、顕著にパフォーマンスが向上します。配列 DML コマンドでは作成される TCP/IP パッケージの数が減るためです。
- クライアント側の CPU 負荷が低下します。ほとんどの場合にサーバーで配列コマンドの処理をしなければならないためです。
- 理論上の速度が 1 秒あたり 100,000 レコードを越えることはあまりありません。通常はサーバーでトリガやインデックスを評価しなければならないためです。
- 1,000,000 レコードを越えるような非常に大規模なバッチ挿入の場合には、最大のパフォーマンスが得られるよう、主キー以外のインデックスを一度削除してから再作成することを検討してください。