web-dev-qa-db-ja.com

BCPは、最後の「SQL Serverに送信された1000行。合計送信数:...」の後で停止します。

SQL Server 2005の一括コピープログラムBCPを次のように実行しました。

bcp mydb.dbo.mytbl in myfile.blk -c -S mysvr -U mylogin -P mypass

そして、それは実行され、次のように出力を生成しました:

Starting copy...
1000 rows sent to SQL Server. Total sent: 1000
...
1000 rows sent to SQL Server. Total sent: 55000

しかし、それは止まりました。カーソルはプロンプトに戻りませんでした。「...コピーされた行」を受け取りませんでした。メッセージ。

ターゲットテーブルをクエリしてみましたが、インポートしたい行が既に表示されています。

コンソールを終了しますか?ロールバックしますか?

7
Endy Tjahjono

すべてのデータをSQL Serverに送信しましたが、データはソートバッファーにのみ配置されているため、プロセスがハングしているように見えます。宛先のテーブルにはまだ到達していません。

テーブルにインデックスがある場合、SQL Serverはデータを挿入する前に必要なインデックス順にソートします。データセットが大きい場合、インデックスが多数ある場合、またはSQL Serverのソートメモリが不足している場合、このプロセスにはかなりの時間がかかることがあります。インデックスおよび既存のテーブルデータの存在も、SQL Serverが最適化された最小ログ挿入を使用する機能に影響を与える可能性があります。

最小限のログに記録された挿入がないと、各行がトランザクションログに完全に記録されるため(挿入後の回復を確実にするために必要な情報を含む)、挿入プロセス(ソート後)も遅くなります。

いくつかのbcpオプションを指定して、最小限のログの挿入を実現できます。効率的な一括操作をサポートするためにデータベースの復旧モデルを一時的に変更するなど、他の対策も必要になる場合があります。挿入前に非クラスター化インデックスを削除し、後でそれらを再構築することも、多くの場合最適な戦略です。

複雑なトピックの主なポイントを要約するには:

  • 最小限のログの挿入をサポートする復旧モデルを使用する
  • TABLOCKヒントを指定します(正確な構文は挿入方法によって異なります)
  • ORDERヒントを指定し、データソースがクラスタリングキーによって事前にソートされていることを確認します
  • トリガーと制約を無効にする
  • 可能であれば空のテーブルにロードします

詳細については、以下を参照してください。

一括挿入パフォーマンスの最適化 およびリンクされたページ

SQL Server 2008以降の場合:

データ読み込みパフォーマンスガイド

2
Paul White 9

3時間後、ようやくプロンプトが表示されました。

55837 rows copied.
Network packet size (bytes): 4096
Clock Time (ms.) Total     : 10582641 Average : (5.28 rows per sec.)

行が既に挿入されているため、なぜすぐに戻らないのかはまだわかりませんが。私の推測では、インデックスの再構築が行われました。

次にコンソールがハングアップしたときに、コンソールを終了してみます。

2
Endy Tjahjono