web-dev-qa-db-ja.com

単一のテーブルに並列に挿入する最速の方法

私の会社は、寄生的になった共生パートナーシップによって呪われています。寄生虫からデータを取得するには、非常に遅いodbc接続を使用する必要があります。最近、クエリを並列に実行することでスループットを向上できることに気付きました(同じテーブルでも)。

データを抽出してローカルテーブルに移動したい、特に大きなテーブルがあります。クエリを並行して実行すると、データをより速く取得できますが、これにより、複数のクエリから同じテーブルに一度にデータを書き込もうとすると問題が発生する可能性があることも想像できます。

クエリを並行して使用する速度の向上を利用できるように、この状況を最適に処理する方法について、どのようなアドバイスをいただけますか?

編集:ここでいくつかの素晴らしいフィードバックを受け取りましたが、リンクサーバー(odbcドライバーを使用)を介してデータをプルしているという事実については完全には明確ではなかったと思います。つまり、通常のINSERTステートメントを実行でき、SqlBulkCopyまたはBULK INSERTよりもパフォーマンスが向上すると思います(実際には、BULK INSERTがオプションになるとは思いません)。

15
Brandon Moore

読んだことがありますか 1時間以内に1TBをロード

  1. 使用可能なCPUと同じ数のロードプロセスを実行します。 CPUが32個ある場合は、32個の並列ロードを実行します。 CPUが8つある場合は、8つの並列ロードを実行します。
  2. 入力ファイルの作成を制御できる場合は、並行して実行するロードスレッドの数で均等に割り切れるサイズにしてください。また、パーティションの切り替え戦略を使用する場合は、すべてのレコードが1つのパーティションに属していることを確認してください。
  3. SQL Serverマシンでプロセスを実行している場合は、BCPの代わりにBULK挿入を使用してください。
  4. テーブルのパーティション分割を使用して、さらに8〜10%を取得します。ただし、入力ファイルがパーティション分割機能と一致するように保証されている場合に限ります。つまり、1つのファイル内のすべてのレコードが同じパーティションにある必要があります。
  5. 一度に行がロックされないようにするには、TABLOCKを使用します。
  6. 複数のストリームを1つのテーブルにインポートする場合は、ROWS PER BATCH = 2500またはこれに近い値を使用します。

SQL Server 2008の場合、 標準のINSERT SELECTの最小ロギング を利用できる特定の状況があります。

SQL Server 2008は、最小限のログで処理できるメソッドを強化します。最小限にログに記録される通常のINSERTSELECTステートメントをサポートします。さらに、トレースフラグ610をオンにすると、SQL Server 2008は、新しいページの割り当てを引き起こす新しいキー範囲の空でないBツリーに対する最小限のログ記録をサポートします。

12
8kb

コード、つまりc#でこれを実行しようとしている場合は、(System.Data.SqlClient名前空間で)SqlBulkCopyを使用するオプションがあり、この記事でこれを並行して実行できることが示唆されています。

http://www.adathedev.co.uk/2011/01/sqlbulkcopy-to-sql-server-in-parallel.html

4
Chris Moutray

万が一SQL2014にアップグレードした場合は、並行して挿入できます(互換性レベルは110である必要があります)。これを参照してください: http://msdn.Microsoft.com/en-us/library/bb510411%28v=sql.120%29.aspx

1
Fat Shogun