11

大量のデータを CSV (300 万行以上) からデータベースにロードする最も効率的な方法は何ですか。

  • データをフォーマットする必要があります (たとえば、名前の列を姓と名に分割する必要があるなど)。
  • 可能な限り効率的にこれを行う必要があります。つまり、時間の制約があります

C# アプリケーションを使用して行ごとにデータを読み取り、変換し、ロードするオプションを支持しますか? これは理想的ですか、そうでない場合、私のオプションは何ですか? マルチスレッドを使用する必要がありますか?

4

7 に答える 7

5

I/O バウンドになるため、マルチスレッド化によって必ずしも高速になるとは限りません。

前回これを行ったときは、約 12 行の C# でした。あるスレッドでは、プラッタからデータを読み取ることができるのと同じくらい速くハードディスクを実行しました。ソース ファイルから一度に 1 行ずつ読み取ります。

自分で書きたくない場合は、FileHelpersライブラリを試すことができます。Sébastien Lorion の作品もご覧ください。彼の CSV リーダーは、パフォーマンスの問題に対処するために特別に作成されています。

于 2010-04-14T22:35:28.827 に答える
3

csvreaderを使用して、CSV をすばやく読み取ることができます。

SQL Server を使用していると仮定すると、csvreader をCachedCsvReader使用してデータを DataTable に読み込み、これをSqlBulkCopyで使用して SQL Server にロードできます。

于 2010-04-14T22:49:08.240 に答える
2

私はあなたの解決策に同意します。一度に 1 行ずつファイルを読み取ると、ファイル全体を一度にメモリに読み取るオーバーヘッドが回避されます。これにより、アプリケーションが迅速かつ効率的に実行され、主にファイルからの読み取り (比較的高速) と行の解析に時間がかかります。 . CSV に改行が埋め込まれていないか注意してください。使用している特定の CSV 形式が実際にデータ内の引用符の間に改行を出力するかどうかはわかりませんが、もちろん、このアルゴリズムを混乱させる可能性があります。

また、後続の外部キーに使用する必要がある生成されたキー値を取得する際に問題が発生しない場合は、データベースに送信する前に挿入ステートメントをバッチ処理することをお勧めします (1 つの文字列に多くの挿入ステートメントを含める)。生成されたキー値を取得する必要はありません)。SQL Server (それを使用している場合) はバッチごとに 2200 個のパラメーターしか処理できないため、それを考慮してバッチ サイズを制限してください。また、パラメーター化された TSQL ステートメントを使用して挿入を実行することをお勧めします。ファイルからレコードを読み取るよりも、レコードを挿入する方が時間がかかると思います。

于 2010-04-14T22:37:21.707 に答える
1

どのデータベースを使用しているかは述べていませんが、言及した言語が C# であることを考えると、SQL Server を想定するつもりです。

BCP を使用してデータをインポートできない場合 (重要な処理が必要な場合はできないように思えます)、SSIS が次に速いオプションである可能性があります。世界で最も優れた開発プラットフォームではありませんが、非常に高速です。合理的な時間枠で自分で作成できるどのアプリケーションよりも確実に高速です。

于 2010-04-14T22:41:05.203 に答える
0

BCP は非常に高速なので、データの読み込みに使用します。文字列操作の場合、データがそこにあれば、SQL で CLR 関数を使用します。このシナリオでは、複雑さが増してパフォーマンスが低下することを除いて、マルチスレッドは役に立ちません。

于 2010-04-14T22:51:00.490 に答える
0

CSV ファイルの内容を 1 行ずつメモリ内の DataTable に読み込みます。DataTable にデータが入力されているときに、データを操作する (つまり、名と姓を分割する) ことができます。

CSV データがメモリに読み込まれたら、SqlBulkCopy を使用してデータをデータベースに送信します。

ドキュメントについては、http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlbulkcopy.writetoserver.aspxを参照してください。

于 2010-04-14T22:58:53.350 に答える
0

本当に C# で実行したい場合は、DataTable を作成して入力し、ターゲット db テーブルを切り捨ててから、System.Data.SqlClient.SqlBulkCopy.WriteToServer(DataTable dt) を使用します。

于 2010-04-14T23:04:06.707 に答える