37

私はデータの大きなCSVファイルのインポートに取り組んできました。通常、100,000レコード未満です。PHPとMySQL(InnoDBテーブル)を使用しています。PHPを使用していくつかのフィールドを変換し、MySQLの前にテキスト処理を行う必要がありました(以下のコードINSERTの一部)。process_note_data()MySQLLOAD DATAは実現可能ではなかったので、提案しないでください。

私は最近、とを使用してMySQLトランザクションを使用することにより、このプロセスの速度を改善しようとしましSTART TRANSACTIONCOMMIT。パフォーマンスの向上は驚くべきものでした。処理時間は20分の1に短縮されました。したがって、20分のプロセスには約1分しかかかりませんでした。

質問。

1.)なぜこのようなパフォーマンスの向上(20分から1分)があったのか誰かが理解していますか?

2.)100,000レコードでトランザクションがどれだけ大きくなるかについて心配する必要がありますか?

3.)トランザクションでの多数の挿入や更新を考慮する必要がありますか?

/*
 * Customer Notes Data:
 * Rows are either a meeting, call or note!
 */
$row = 1;
$data = array();
$fields = array();
$line = '';

$db->query('SET autocommit=0;');
$db->query('START TRANSACTION;');

if (($handle = fopen("modules/".$currentModule."/Data/customernote.csv", "r")) !== FALSE) {
  while (($data = fgetcsv($handle, 4096, ',', '"')) !== FALSE && $row < 999000) {
    //Row 1 - CSV header row with field names
    if ($row == 1) {
      $csv_fields = $data;
    } elseif ($row > 1) {
      $fields = $this->process_note_data($data, $csv_fields, $row);
    }
    $row++;
  } // end while
  fclose($handle);
}

$db->query('COMMIT;');
$db->query('SET autocommit=1;');

注:テキスト/フィールド処理は呼び出しで実行され、呼び出し先はステートメントコード$this->process_note_data()を持つ別のヘルパークラスを呼び出します。INSERTすべてのコードを含めるのに十分なスペースがありませんでした。$db->query()MySQLクエリの典型的なデータベースオブジェクトです。

4

2 に答える 2

26
  1. このリンクを確認してください:

    https://dev.mysql.com/doc/refman/5.5/en/optimizing-innodb-transaction-management.html

    InnoDBは、トランザクションがデータベースに変更を加えた場合、トランザクションがコミットされるたびにログをディスクにフラッシュする必要があります。(デフォルトの自動コミット設定のように)各変更の後にコミットが続く場合、ストレージデバイスのI / Oスループットにより、1秒あたりの潜在的な操作の数に上限が設定されます。

  2. 大きなトランザクションは、コミット中のパフォーマンスに影響を与える可能性があります(上記を確認してください)

  3. ロールバックの場合のみですが、一部の設定を使用して最適化される場合があります(リンクを確認してください)

于 2013-02-03T17:47:55.160 に答える
22

.Netでの私自身の小さなテスト(4フィールドpr。レコード):

1レコードを挿入、トランザクションなし:60ミリ秒

トランザクションを使用して1レコードを挿入:158ミリ秒

トランザクションを使用して200レコードを挿入し、各レコードの後に​​コミットします:17778 ミリ秒

トランザクションを使用せずに200レコードを挿入:4940ミリ秒

トランザクションを使用して200レコードを挿入し、最後のレコードの後に​​のみコミットします:4552ミリ秒

トランザクションを使用して1000レコードを挿入し、最後のレコードの後に​​のみコミットします:21795ミリ秒

デンマークのクライアント、ベルギーのサーバー(Googleクラウドf1-micro)。

私はこれをコメントに入れるつもりでしたが、フォーマットが良くありません....だからここに事前に謝罪します;-)

于 2016-01-29T12:33:10.310 に答える