12

質問

大きな(> 1GB)XMLファイルをMySQLデータベースにダンプする最速の方法は何ですか?

データ

問題のデータは、StackOverflow Creative CommonsDataDumpです。

目的

これは、私が構築しているオフラインのStackOverflowビューアで使用されます。これは、インターネットにアクセスできない場所で学習/コーディングを行うことを検討しているためです。

プロジェクトが終了したときに、これを残りのStackOverflowメンバーシップにリリースして、自分で使用できるようにしたいと思います。

問題

もともと、私はXMLからの読み取り/DBへの書き込みを一度に1レコードずつ行っていました。これは私のマシンで実行するのに約10時間かかりました。私が使用しているハックタスティックコードは、500レコードを配列にスローし、挿入クエリを作成して500すべてを一度にロードします(例: " INSERT INTO posts VALUES (...), (...), (...) ... ;")。これは高速ですが、実行にはまだ数時間かかります。明らかにこれは最善の方法ではないので、このサイトの頭脳がより良い方法を知ってくれることを願っています。

制約

  • デスクトップアプリケーション(つまり、WinForms)としてC#を使用してアプリケーションを構築しています。
  • データベースとしてMySQL5.1を使用しています。これは、「LOAD XML INFILE filename.xml」などの機能はMySQL 5.4以降でのみ使用できるため、このプロジェクトでは使用できないことを意味します。この制約は主に、プロジェクトが私以外の人々にも役立つことを望んでいるためであり、MySQLのベータ版を使用するように強制したくはありません。
  • データロードをアプリケーションに組み込みたい(つまり、「このアプリケーションを実行する前に、「foo」を使用してMySQLにダンプをロードする」という指示はありません)。
  • MySQL Connector / Netを使用しているので、MySql.Data名前空間内のすべてが受け入れられます。

あなたが提供できるどんなポインタにも感謝します!


これまでのアイデア

XMLファイル全体を列にロードし、XPathを使用して解析するストアドプロシージャ

  • ファイルサイズは、デフォルトで1 MBに設定されているmax_allowed_pa​​cket変数の制限の対象となるため、これは機能しませんでした。これは、データダンプファイルのサイズをはるかに下回っています。
4

8 に答える 8

12

これには 2 つの部分があります。

  • xml ファイルの読み取り
  • データベースへの書き込み

xml ファイルを読み取る場合、このリンクhttp://csharptutorial.blogspot.com/2006/10/reading-xml-fast.htmlは、ストリーム リーダーを使用して 2.4 秒で 1 MB を読み取ることができることを示しています。つまり、2400 秒または1 GB のファイルで 40 分 (計算が遅い場合)。

私が読んだことから、MySQL にデータを取得する最速の方法は、LOAD DATA を使用することです。

http://dev.mysql.com/doc/refman/5.1/en/load-data.html

そのため、xmlデータが読み込める場合は、LOAD DATAで使えるファイルに書き込んでからLOAD DATAを実行してください。合計時間は、経験している時間よりも短い場合があります。

于 2009-09-24T17:45:38.887 に答える
1

わかりました、私はここでばかになり、あなたの質問に質問で答えます。

なぜデータベースに入れるのですか?

もしも…もしも…ローカルドライブのファイルにxmlを書き込んで、必要に応じて、データベースにインデックス情報を書き込んでいます。これは、データベースをロードしようとするよりもはるかに高速に実行され、はるかに移植性が高くなります。その上で必要なのは、検索方法とリレーショナル参照のインデックス作成方法だけです。検索には多くのヘルプが必要であり、リレーショナルな側面は簡単に構築できる必要がありますか? 各ファイルに単一の投稿が含まれ、すべての回答とコメントがすぐそこに含まれるように、情報を書き直すことを検討することもできます。

とにかく、私の 2 セントだけです (そして、それは 10 セント硬貨の価値はありません)。

于 2009-09-28T21:03:02.453 に答える
1

これをスピードアップするのに役立ついくつかの考えがあります...

  1. クエリのサイズを微調整する必要がある場合があります。多くの場合、大きなステートメントは解析時間のコストが高くなり、遅くなります。500 が最適かもしれませんが、おそらくそうではないので、少し調整することができます (それ以上になることもあれば、それ以下になることもあります)。

  2. マルチスレッド化します。システムが処理でまだ平坦化されていないと仮定すると、データをチャンクに分割し、スレッドで処理することで、いくらかの利益を得ることができます。繰り返しますが、最適なスレッド数を見つけるのは実験的なことですが、多くの人がマルチコア マシンを使用しており、CPU サイクルに余裕があります。

  3. データベースの面では、テーブルが可能な限り裸であることを確認してください。インデックスをオフにして、インデックスを作成する前にデータをロードします。

于 2009-09-29T01:09:41.893 に答える
1

SqlBulkCopy ROCKS. 30分の機能を4秒に変えるために使用しました。ただし、これは MS SQL Serverにのみ適用されます。

作成したテーブルの制約を確認することをお勧めしますか? データベース、制約などのすべてのキーを削除すると、データベースは挿入の作業を減らし、再帰的な作業を減らします。

次に、空のデータベースに挿入する場合のサイズ変更を防ぐために、大きな初期サイズでテーブルをセットアップします。

最後に、MySQL 用の一括コピー スタイルの API があるかどうかを確認します。SQL Server は基本的に、データがディスクに送られるようにデータをフォーマットし、SQL サーバーはストリームをディスクにリンクし、データを送り込みます。次に、挿入ごとに 1 回ではなく、すべてのデータに対して 1 回の整合性チェックを実行するため、パフォーマンスが大幅に向上します。

MySQL は必要ですか? Visual Studio を使用していて、データベースのパフォーマンスやサイズが低い場合、SQL Server を使用すると作業が楽になります。

于 2009-09-29T01:18:46.390 に答える
0

PostgreSQLでは、バルクデータを取得するための絶対的な最速の方法は、すべてのインデックスとトリガーを削除し、MySQLのLOAD DATAと同等のものを使用してから、インデックス/トリガーを再作成することです。この手法を使用して、約10分で5GBのフォーラムデータをPostgreSQLデータベースにプルします。

確かに、これはMySQLには当てはまらないかもしれませんが、一見の価値があります。また、このSO質問の回答は、これが実際にMySQLにとって実行可能な戦略であることを示唆しています。

簡単なグーグルは、MySQLのLOADDATAのパフォーマンスを向上させるためのいくつかのヒントを見つけました。

于 2009-09-29T23:40:32.260 に答える
0

あなたが望む答えではありませんが、mysql c api にはmysql_stmt_send_long_data関数があります。

于 2009-09-24T17:25:13.967 に答える
0

上記のコメントの 1 つで、MSSQL を検討していることに気付いたので、これを投稿しようと思いました。SQL Server には、大量の XML データを SQL Server データベースにインポートするように設計された SQML​​XMLBulkLoad というユーティリティがあります。SQL Sever 2008 バージョンのドキュメントは次のとおりです。

http://msdn.microsoft.com/en-us/library/ms171993.aspx

以前のバージョンの SQL Server にもこのユーティリティがあります

于 2009-09-26T07:29:59.923 に答える
0

これはまったく役に立ちますか?これは、XML ファイル全体を列にロードし、XPath を使用して解析し、テーブルを作成してそこからデータを挿入するストアド プロシージャです。ちょっとクレイジーに思えますが、うまくいくかもしれません。

于 2009-09-21T19:23:11.257 に答える