2

テスト用に、データベースに約 5 億行のガベージ データを挿入しようとしています。現在、PHP スクリプトがいくつかのSELECT/INSERTステートメントをそれぞれ a 内にループしていますが、TRANSACTION 明らかにこれは最善の解決策ではありません。テーブルは InnoDB (行レベルのロック) です。

プロセスを(適切に)フォークするかどうか疑問に思っていますが、これによりプロセスがスピードアップしINSERTますか?このままだと140時間はかかります。次の 2 点が気になります。

  1. ステートメントが書き込みロックを取得する必要がある場合INSERT、複数のプロセスが同時に同じテーブルに書き込むことができないため、フォークは役に立たなくなりますか?

  2. 私はSELECT...LAST_INSERT_ID()(の中でTRANSACTION)を使用しています。INSERT複数のプロセスがデータベースに接続している場合、このロジックは壊れますか? フォークごとに新しいデータベース接続を作成できたので、これで問題が回避されることを願っています。

  3. いくつのプロセスを使用する必要がありますか? クエリ自体はシンプルで、2GB RAM の通常のデュアルコア開発ボックスを使用しています。8 つのスレッドを使用するように InnoDB をセットアップしました ( innodb_thread_concurrency=8) が、8 つのプロセスを使用する必要があるかどうか、またはこれが一致について考える正しい方法であるかどうかはわかりません。

ご協力いただきありがとうございます!

4

2 に答える 2

7

MySQL のドキュメントには、多数のレコードの効率的な挿入に関する説明があります。明らかな勝者は、LOAD DATA INFILEコマンドの使用であり、その後に複数の値リストを挿入する挿入が続くようです。

于 2009-09-02T03:44:56.087 に答える
4

1) はい、ロック競合が発生しますが、innodb は挿入を試みる複数のスレッドを処理するように設計されています。確かに、それらは同時に挿入されませんが、挿入のシリアル化を処理します。トランザクションを明確にクローズし、できるだけ早くそれを行うようにしてください。これにより、可能な限り最高の挿入パフォーマンスが得られます。

2) いいえ、last_insert_id() は接続固有であるため、スレッドごとに 1 つの接続があれば、このロジックは壊れません。

3) これは、理解するためにベンチマークする必要があるものの 1 つです。実際、私はプログラムを自己調整させます。8 つのスレッドで 100 回の挿入を実行し、実行時間を記録します。次に、半分の数と 2 倍の数で再試行します。どちらが速いかを判断してから、その数に近いスレッド数の値をベンチマークしてください。

一般に、この種のものを常にベンチマークして、どちらが速いかを確認する必要があります。それについて考えて書き上げるのにかかる時間の量で、おそらくすでに暫定的な数値を持っている可能性があります.

于 2009-09-02T03:42:25.297 に答える