SqlBulkCopyを使用して行を挿入する

linq-to-sql sqlbulkcopy sql-server transactions

質問

私はSqlBulkCopyを使用するために私のLinqの一部をSqlコードに切り替えています。問題は2つのテーブルに複数の行を2つ挿入する必要があることです。

このサービスは10,000リンク(サイトマップ、バックリンクビルダーなどからインポートされたもの)のバッチを取得し、フィードごとのXのRSSフィードに集約して集約します。問題は、すでに3200万行のテーブルがあることです。もし私がlinqからsqlへの挿入をしているのであれば、10,000のリンクをロードするのに5〜10分の間にサイトのトラフィックに依存します。

構造は非常に基本的です。

フィードは、 ID bigint(PK)、タイトルvarchar(1000)、説明varchar(1000)、Published datetime、集約datetimeヌル、ShortCode varchar(8、古くから挿入されていませんが、

項目 :ID bigint(PK)、FeedId bigint(FK)、タイトルvarchar(1000)、説明varchar(1000)、Published datetime、ShortCode vintar(8)[古くから挿入されていません。 null [挿入後に更新されたID(パーティション化で使用される)]

FutureIDems :ID bigint(PK)、FeedId bigint(FK)、タイトルvarchar(1000)、説明varchar(1000)、Published datetime、ShortCode vintar(8)[古くから挿入されていませんが、 null [挿入後に更新されたID(パーティション化で使用される)]

OldItems :ID bigint(PK)、FeedId bigint(FK)、タイトルvarchar(1000)、説明varchar(1000)、Published datetime、ShortCode vintar(8)[古くから挿入されていませんが、 null [挿入後に更新されたID(パーティション化で使用される)]

したがって、フィードのサイズが20の場合は、Feedsテーブルに500個のInsertを入れてからItemsテーブルに10000を挿入し、Updateを実行してShortIdをIdに設定します。一晩に1回、データを別の2つのテーブルに分割し、将来のアイテムをアイテムテーブルに移動するジョブが実行されます。

私は、SqlBulkCopyがmintuesの問題で2千万行を処理できることを読んだが、FK Constraintを使用して複数のテーブルにそのような良い例を見つけることはできない。

私たちのSQLサーバは、特にこのアプリケーションのための "モンスター"です。 SQL 2008 R2 Web、Windows 2008 R2 Enterprise、12GB RAM、Dual 4 core Xeons @ 2.8ghzです。

当社のWebサーバーは、データベースサービスのないクローンです。

リンクを挿入するとCPUは約85%実行され、データベースはRAMをいっぱいにします。

SqlBulkCopyがうまくいかない場合、提案は歓迎です。私たちは怒っている顧客に支払っています。私はDBAではありません。普通のプログラマーです。

受け入れられた回答

SqlBulkCopyは、通常の挿入よりも実際に高速です。しかし、1秒あたり1000インサートを実行するジョブを10000 /秒を実行するジョブに変換できるので、より高速です。 10分で10000回しかリンクできない場合は、別の問題を抱えている必要があります。バルクコピーが解決しそうにないものです。

最初に10000リンクを挿入するのに非常に時間がかかる理由を調べる必要があります。あなたが理解した後でなければ、SqlBulkCopyへの移行が解決策であるかどうかを判断する呼び出しを行うことはできません。私はあなたがDBAではないことを理解していますが、SQL Serverのパフォーマンスをトラブルシューティングするためのホワイトペーパー「dbaish」をお送りします: Waits and Queues 。これはクッキーカッターレシピソリューションではなく、実際にはSQL Serverのパフォーマンスのボトルネックを特定する方法を教える方法論です。

あなたの質問に対処する:制約があるときにSqlBulkCopyを使う方法は?より一般的な質問は、制約がある場合に一括挿入操作を行う方法です。重大なボリュームの場合、実際には制約を無効にし、一括アップロードを実行してから制約を有効に戻します。ダウンタイムを最小限に抑えたより効率的なオンライン操作(データベースは基本的に制約が無効になっている間は「ダウン」しています)では、別の戦略、つまりステージング表のデータを事前ロードし、検証してからパーティションスイッチ操作を使用して効率的にデータ転送するを参照してください。


人気のある回答

私は単純な一括挿入を使用するだけであなたの本当の問題は、他のテーブルの最初の挿入からフィードIDが必要なことだと思います。ここに私がすることがあります。ステージングテーブルに挿入するには、バルク挿入を使用します。次に、ストアドプロシージャを使用して、実テーブルへの挿入をセットベースの方法で行います。フィード・テーブルへの最初の挿入時にoutput句を使用すると、他のテーブルへの挿入に必要なフィードIDを持つテーブル変数を取得できます。



ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ