13

さまざまな CSV フィードを介して大量のデータを更新するためのシステムを構築しています。通常、フィードの各行をループし、選択クエリを実行してアイテムが既に存在するかどうかを確認し、存在するかどうかに応じてアイテムを挿入/更新します。

この方法はあまりスケーラブルではなく、より大きなフィードでサーバーに打撃を与える可能性があると思います。私の解決策は、アイテムを通常どおりループしてメモリに保存することです。次に、約 100 個のアイテムごとに、それらの 100 個のアイテムを選択し、一致するデータベース内の既存のアイテムのリストを取得します。次に、insert/update ステートメントを連結してデータベースに実行します。これにより、基本的にデータベースへの移動が削減されます。

これは十分にスケーラブルなソリューションですか? また、大規模なフィードを生産環境にインポートするためのサンプル チュートリアルはありますか?

ありがとう

4

5 に答える 5

14

SQL Server 2008 を使用していることがわかったので、次のアプローチをお勧めします。

  • まず、CSV ファイルをステージング テーブルに一括コピーします。
  • MERGE コマンドを使用して、そのステージング テーブルからターゲット テーブルを更新します。

MSDN のドキュメントと、MERGE コマンドの使用方法に関する優れたブログ投稿を確認してください。

基本的に、実際のデータ テーブルとステージング テーブルの間のリンクを共通の基準 (共通の主キーなど) で作成し、次に何をするかを定義できます。

  • 行が一致します。たとえば、行がソース テーブルとターゲット テーブルの両方に存在します --> 通常、いくつかのフィールドを更新するか、すべてを無視します。
  • ソースからの行がターゲットに存在しない --> 通常は INSERT の場合

MERGE次のようなステートメントがあります。

MERGE TargetTable AS t
USING SourceTable AS src
ON t.PrimaryKey = src.PrimaryKey

WHEN NOT MATCHED THEN
  INSERT (list OF fields)
  VALUES (list OF values)

WHEN MATCHED THEN
  UPDATE
    SET (list OF SET statements)
;

もちろん、このON節は必要に応じてさらに複雑になる可能性があります。そしてもちろん、WHENステートメントはより複雑になることもあります。

WHEN MATCHED AND (some other condition) THEN ......

など。

MERGEは、SQL Server 2008 の非常に強力で非常に便利な新しいコマンドです。可能であれば使用してください。

于 2010-02-26T14:46:35.613 に答える
3

あなたのやり方は最悪の解決策です。一般に、レコードを個別にループするという観点から考えるべきではありません。以前は、レコードをループ処理するインポート ツールを社内で作成していました。100 万を超えるレコードを含むファイルを読み込むには、18 ~ 20 時間かかりました (作成時には頻繁に発生することはありませんでしたが、日発生現在)。

2 つのオプションがあります。最初に一括挿入を使用してステージング テーブルに読み込み、そのテーブルで必要なクリーンアップを行います。レコードが既に存在するかどうかをどのように判断していますか? 更新を決定するフィールドのステージング テーブルに結合することで、セットベースの更新を構築できるはずです。多くの場合、ステージング テーブルに一致するレコードの ID の列を追加し、クエリを使用してそれを入力し、更新を行います。次に、対応する ID を持たないレコードの挿入を行います。一度にすべてを実行するにはレコードが多すぎる場合は、バッチで実行することをお勧めします (これはループです) が、バッチを一度に 1 レコードよりもかなり大きくします (私は通常 2000 から開始し、次にバッチで多かれ少なかれできるかどうかを判断するのにかかる時間)。

2008 にもマージ ステートメントがあると思いますが、まだ使用する機会がありません。オンラインの本で調べてください。

別の方法は、速度が最適化された SSIS を使用することです。ただし、SSIS は複雑なものであり、学習曲線は急勾配です。

于 2010-02-26T14:36:10.020 に答える
2

1 つの方法は、CSV を DataTable (または DataReader の可能性が高い) にロードし、SqlBulkCopy を使用して結果を一括処理することです。

http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlbulkcopy.aspx

非常に効率的で、列のマッピングを行うことができます。ヒント - SqlBulkCopy を使用して列をマップすると、大文字と小文字が区別されます。

于 2010-02-26T13:48:38.843 に答える
0

あなたはここであなた自身を転がす必要がありますか?SQL Serverが一括インポートを使用してデータをロードし、インポートが完了したらデータベース内の重複を処理できるような方法でデータを提供することは可能でしょうか?

大量のデータを処理するということになると、私の経験では、データベースでの作業がはるかに速く、リソースをあまり消費しないという傾向があります。

于 2010-02-26T14:07:03.763 に答える
0

別のアプローチは、ファイル全体を操作するために、サーバー上のサーバーに.Netストアドプロシージャを作成することです。

ただし、Kris Krauseのソリューションよりも詳細な制御が必要な場合にのみ、私は可能な限りシンプル(かつ再利用可能)に保つのが大好きです...

于 2010-02-26T13:56:05.780 に答える