最近のアクセス:
New コマンドにおける Blocking 節

 
 
大量のレコードを挿入する必要があり、スループットが問題となる場合には、DBMS へのラウンドトリップを減らすことで解決できることがあります。概要については「データ更新のブロッキング」を参照してください。
大量のレコードを挿入する必要がある場合、レコードを 1 つずつ挿入するのではなくブロックで挿入するとパフォーマンスが大幅に向上します (「ブロック挿入のパフォーマンス」を参照してください)。パフォーマンスがどの程度向上するかは、行数およびブロックのサイズによって異なります。
New 構文は、次に示す「Blocking NumericExpression」のオプション節に対応しています。この節があると、ブロック (バッチ) 挿入メカニズムが有効となり、ブロックごとのレコードの数をコントロールします。「New コマンド」で、完全な構文を参照してください。

構文

New [ Blocking <数値式> ] ....
[ When Duplicate ] ....EndNew
ここで <数値式> は 1 ~ 2,147,483,647 の数値を返すエクスプレッションです。

使用例:

for each 
   ...
   new blocking 100
      Att1 = ...
      Att2 = ...
   when duplicate
      Att2 = ...
  endnew
endfor 

挿入が実行されるタイミング

実際の挿入は、各ブロックの最後に実行されます。New コマンドにはブロッキング因数 N があり、繰り返し構造 (例: For Each コマンド) の中にあるとします。For Each コマンド (およびその中にある New コマンド) の本文が実行されるたびに新しいレコードが挿入されることはなく、サイズ N のメモリーブロック (バッファー) に追加されます。その後バッファーがいっぱいになると、ブロック全体を挿入するため、特別な (多数行の) 挿入がデータベースに送信されます。追加される N レコードの一部が重複していることが判明した場合、特別な挿入は失敗となります。次に示す単純な挿入コマンドを使用して、N ブロックの全レコードの挿入が 1 件ずつ行われます。
注: 最後のブロック (N レコード未満を含む) は次のように挿入されます:

実装

ブロックの保存が有効になっている場合、グループについて生成されたコードは次のようになります:
Add record to block
NumberOfRecords += 1
if NumberOfRecords >= NumericExpression
    Insert Record Block	//一括挿入コマンド
    When Duplicate  //レコード挿入に失敗
    /* ブロック内の全レコードをスキャンして重複の有無を確認 */
         For each record in block
             Insert Record	//単純な挿入コマンド
             When Duplicate
                 /* 重複する場合のユーザーコード */
             endwhenduplicate
         endfor
    endwhenduplicate
    NumberOfRecords = 0
endif
重複キーエラーの場合、コードはブロックのレコードを 1 つずつ挿入しようとし、重複キーを生成するレコードに対して When Duplicate コードを実行してブロックのレコードを一掃します。Rollback コマンドが実行された場合、トランザクションのロールバックが実行され、挿入準備の完了しているブロック (バッファー) 内のレコードがすべて削除されます。

適用範囲

この節は次のプラットフォームではサポートされません:  
  • Java - DB2 UDB
  • .NET - MySQL
  • .NET - Informix
  • .NET - PostgreSQL
  • .NET Core - PostgreSQL
注:
GeneXus 17 では、Blocking 節がプラットフォームでサポートされない場合、次のような内容のメッセージがスローされます: spc0222 %1% の Blocking 節は現時点で行 %2% から始まるグループでサポートされていません。

よくある質問

レコードは、ブロックで挿入するのと個別に挿入するのではどちらが良いですか?

ロジックや When Duplicate コードの頻度などによって異なります。挿入直後にそのレコードにアクセスする必要がある場合は、ブロック挿入を使用することはできません。重複するレコードが多い場合は、通常はブロック挿入を使用しないほうが良いでしょう。

ブロックにレコードは何件含めるべきですか?

ブロックごとのレコード数は場合によって異なります。決められた数はありません。

最後のブロックはいつ挿入されますか (レコード数がブロックごとのレコード数の倍数でない場合) ?


実行時にブロックごとのレコード数を変更するとどうなりますか?

NumericExpression が変数のエクスプレッションである場合、その値は各ブロックの最初の挿入時にのみ指定できます。

When Duplicate コード内で Return があるとどうなりますか?

When Duplicate コードは Return 直前まで実行されます。プログラムの残りに対しては実行されません (When Duplicate コードは、カーソルバッチのバッファーが完了した場合または Commit コマンドが実行された場合に呼び出される新しいルーチンにおいて生成されます)。

When Duplicate コード内で Do または Call があるとどうなりますか?

どちらの場合も、対応する呼び出しが行われます。

Commit コマンドが実行されるとどうなりますか?

グループの範囲内で Commit コマンドを実行すると、保留中の更新/削除がすべてサーバーに送信されます。つまり、レコードを処理するたびに Commit コマンドを発行しないでください。ブロッキングはパフォーマンスには影響しません。

ロールバックが実行されるとどうなりますか?

Rollback コマンドが実行されると、トランザクションのロールバックが実行され、最後のコミット後に挿入されたレコードがすべて削除されます。完了したブロック、挿入されたブロック、または完了していないブロックに対応するレコードはすべて削除されます。









サブページ
Created: 14/09/18 03:16 by Admin Last update: 22/04/05 18:19 by Admin
カテゴリ
Powered by GXwiki 3.0