一括コピー バッチ サイズの管理
適用対象: SQL Server Azure SQL Database Azure SQL Managed Instance Azure Synapse Analytics Analytics Platform System (PDW)
一括コピー操作でバッチを使用する主な目的は、トランザクションのスコープを定義することです。 一括コピー関数では、バッチ サイズが設定されていないと、一括コピー全体を 1 つのトランザクションと見なします。 バッチ サイズが設定されている場合、各バッチはそのバッチの終了時にコミットされるトランザクションで構成されます。
バッチ サイズを指定せずに一括コピーを実行し、エラーが発生した場合は、一括コピー全体がロールバックされます。 実行時間が長い一括コピーの復旧には時間がかかることがあります。 バッチ サイズを設定すると、各バッチが 1 つのトランザクションと見なされ、各バッチがコミットされます。 エラーが発生した場合は、最後の未解決のバッチだけがロールバックされます。
バッチ サイズは、ロックのオーバーヘッドにも影響を与えることがあります。 SQL Server に対して一括コピーを実行する場合は、 bcp_control を使用して TABLOCK ヒントを指定して、行ロックの代わりにテーブル ロックを取得できます。 1 つのテーブル ロックを設定すると、一括コピー操作全体のオーバーヘッドを最小限に抑えることができます。 TABLOCK を指定しないと各行がロックされるので、一括コピーの実行中にすべてのロックを保持するオーバーヘッドにより、パフォーマンスが低下することがあります。 トランザクションの長さだけロックが保持されるので、バッチ サイズを指定すると、定期的にコミットが発生して、その時点で保持されているロックが解放されるため、この問題を解決できます。
大量の行を一括コピーする場合、1 つのバッチを構成する行数がパフォーマンスに大きな影響を与えることがあります。 推奨バッチ サイズは、実行する一括コピーの種類によって異なります。
SQL Server に一括コピーする場合は、TABLOCK の一括コピー ヒントを指定し、大きなバッチ サイズを設定します。
TABLOCK を指定しない場合は、バッチ サイズを 1,000 行未満に制限します。
データ ファイルから一括コピーする場合、バッチ サイズは、bcp_execを呼び出す前に BCPBATCH オプションを使用してbcp_controlを呼び出すことによって指定されます。 bcp_bindとbcp_sendrowを使用してプログラム変数から一括コピーする場合、バッチ サイズは、bcp_sendrow x 回呼び出した後にbcp_batchを呼び出すことによって制御されます。ここで、x はバッチ内の行数です。
バッチはトランザクションのサイズを指定するだけでなく、ネットワーク経由でサーバーに行を送信するときにも影響を与えます。 一括コピー関数は、通常、ネットワーク パケットがいっぱいになるまで bcp_sendrow から行をキャッシュし、完全なパケットをサーバーに送信します。 ただし、アプリケーションが bcp_batchを呼び出すと、現在のパケットが入力されているかどうかに関係なく、サーバーに送信されます。 バッチ サイズを非常に小さくすると、いっぱいになっていないパケットが大量にサーバーに送信されるので、パフォーマンスが低下することがあります。 たとえば、すべてのbcp_sendrowの後にbcp_batchを呼び出すと、各行が個別のパケットで送信され、行が非常に大きい場合を除き、各パケットの領域が無駄になります。 SQL Server のネットワーク パケットの既定のサイズは 4 KB ですが、アプリケーションは、SQL_ATTR_PACKET_SIZE属性を指定 SQLSetConnectAttr を呼び出すことによってサイズを変更できます。
バッチのもう 1 つの副作用は、各バッチが bcp_batchで完了するまで未処理の結果セットと見なされることです。 バッチが未処理の間に接続ハンドルに対して他の操作が試行された場合、SQL Server Native Client ODBC ドライバーは、SQLState = "HY000" と次のエラー メッセージ文字列でエラーを発行します。
"[Microsoft][SQL Server Native Client] Connection is busy with
results for another hstmt."