2009-04-22 45 views

答えて

73

私はインポートユーティリティをSQL Serverインスタンスと同じ物理サーバーに置いています。カスタムIDataReaderを使用して、フラットファイルを解析し、SQLBulkCopyを使用してデータベースに挿入します。一般的なファイルには、約6Mの修飾行があり、1行につき約30バイトの小文字と小文字の5列を平均します。

このシナリオでは、速度とメモリ消費の最適な妥協点として、バッチサイズが5,000であることがわかりました。私は500で始まり、より大きなものを試しました。私は500を平均2.5倍速く500と見積もった.600万行を挿入すると、バッチサイズが5,000の場合は約30秒、バッチサイズが500の場合は約80秒かかります。

10,000は、それほど高速ではありませんでした。 50,000まで移動すると速度は数%向上しましたが、サーバーの負荷が増えるわけではありません。 50,000以上ではスピードの改善は見られなかった。

これは数式ではありませんが、これは別のデータポイントです。

+2

テーブルが空でインデックスがある場合は、考慮すべき点が1つあります。そのような場合は、ここに記載されているようにすべてを1つのバッチにアップロードしたいと思うかもしれません:https://technet.microsoft.com/en-us/library/ms177445(v=sql.105).aspx "最初のバッチの後にテーブルは空ではなくなります。2番目のバッチからデータは完全にログに記録されますが、空のインデックス付きテーブルの場合は、1回のバッチでバルクインポートを実行することを検討してください。 " – Sal

3

これはすべて実装によって異なります。

ネットワークにはどのようなスピードが期待できますか? FormsまたはASP.Netで使用していますか? 進捗状況をユーザーに警告する必要がありますか? 合計ジョブのサイズはどのくらいですか?

バッチサイズを指定せずに一括コピーを実行すると、タイムアウトの問題が発生します。私は1000レコードのようなものから始め、そこからいくつかの調整をするのが好きです。

+0

速度:Webフォーム:はい、ASP.NET:はい、ワイドテーブル:はい、ナローテーブル、はい。何千もの行:はい。何百万もの行:はい。あなたがシナリオを考えることができるなら、私はおそらくそれをやっています。 –

+1

私はこれまでの私の答えを守らなければなりません。私は銀色の弾丸はないと思う。 – Jeremy

24

これは私が探している時間も過ごした問題です。私は、C#コンソールアプリケーション(.Net 2.0)を使用してSQL Server 2005データベースに大規模なCSVファイル(16GB以上、6500万レコード、および成長)をインポートすることを最適化することを検討しています。 にはalready pointed outがありますので、特定の状況に合わせて微調整を行う必要がありますが、最初のバッチサイズは500、テスト値の上下はこれを下回ることをお勧めします。

このMSDN forum postからバッチサイズの値を100と1000の間でテストすることが推奨されており、懐疑的でした。しかし、バッチサイズを100と10,000の間でテストしたところ、私のアプリケーションでは500が最適な値であることがわかりました。 SqlBulkCopy.BatchSizeの値はhereです。

SqlBulkCopy操作をさらに最適化するには、MSDN adviceをチェックしてください。 SqlBulkCopyOptions.TableLockを使用すると、読み込み時間が短縮されます。

+0

私は、サーバー自体で一括コピーコマンドを実行するのがおそらくもっと速くなると思います。 –

12

他の人の言われているように、あなたの環境、特に行のボリュームとネットワークの待ち時間によって異なります。

個人的には、BatchSizeプロパティを1000行に設定して、それがどのように実行されるかを見ていきます。それが機能する場合は、タイムアウトが発生するまで行数を倍増します(例:2000、4000など)。

それ以外の場合、1000でタイムアウトが発生すると、動作するまで行数を半分(たとえば500)減らします。

の差異は、スイートスポットを見つけるまで、最後の2つのバッチサイズの試行間でそれぞれ倍増(成功した場合)または半分(失敗の場合)を維持します。

考慮すべきもう1つの要因は、単一の行のバッチをコピーするのにかかる時間です。タイムアウトは、コピーされる行のバッチがデフォルトで30秒のBulkCopyTimeoutプロパティを超えた場合に発生します。 BulkCopyTimeoutプロパティを60秒間に2倍にしてみてください。これにより、より大きなバッチ行のセットをコピーするための時間が長くなります。たとえば、50,000行のバッチは、30秒の制限時間をわずかに超える約40秒かかるため、60秒までバンプするとパフォーマンスに役立ちます。

関連する問題