0

先に進む前に、これは純粋に直感の問題です。つまり、PHP/MySQL コードの特定のバグを解決するための回答を求めているわけではありません。むしろ、問題を解決するために考慮しなければならない可能性のある問題の範囲を理解したいのです。これらの目的のために、私はコードを投稿したり、スクリプトを添付したりしません。私が何をしたか、何が起こっているかを説明するだけです。

私はPHPスクリプトを書いています

  1. MySQL データベース テーブルに挿入する X レコードの CSV テキスト ファイルを読み取り、該当する場合は重複エントリを更新します。
  2. 上記のレコードを、そのデータ セットの「ルート」テーブルと呼ぶものに挿入します。
  3. 「ルート」テーブルから特定のフィールドのサブセット レコードを選択し、それらのレコードを「マスター」テーブルに挿入します。と
  4. 配布用のマスター テーブルから出力エクスポート テキスト ファイルを作成します。

30 分ごとにスケジュールされた個別の cron タスクを介して処理している CSV ファイルがいくつかあります。さまざまなソースから、ファイルからルート テーブルへの推定 420,000 の挿入トランザクションと、スケジュールされたタスクを介したルート テーブルからマスター テーブルへの別の 420,000 の挿入トランザクションがあります。

タスクの 1 つは、それ自体で約 400,000 レコードの CSV ファイルに関係します。処理にエラーは含まれていませんが、ここに問題があります。MySQL がルート テーブルに正常に挿入されたことを示す 400,000 レコードのうち、実際にルート テーブルに格納されているのは約 92,000 レコードのみです。仕事。

他のスケジュールされたタスクは、それぞれ約 16,000 および 1,000 のトランザクションを処理し、これらのトランザクションは完全に処理されます。実際、トランザクションの数を 400,000 からたとえば 10,000 に減らすと、これらのプロセスも問題なく処理されます。明らかに、それはここでの目標ではありません。

この問題に対処するために、私はいくつかの救済策を試しました...

  1. サーバーのメモリを増やす (および php.ini ファイルの最大制限を増やす)
  2. 拡張メモリを備えた専用データベースを取得する (共有 VPS データベースとは対照的に)
  3. コードを書き直して、メモリを消費し、実行時に fgetcsv() プロセスを処理する格納された配列を大幅に排除する
  4. INSERT DELAYED MySQL ステートメントを使用する (プレーンな INSERT ステートメントではなく)

...そして、これらの救済策はどれも期待どおりに機能していません.

これまでに取られた措置が成功していないことを考えると、この時点でどの範囲の是正措置を検討する必要がありますか? ありがとう...

4

2 に答える 2

0

csv のソース データには、重複したレコードが含まれている可能性があります。csv には 400,000 レコードがありますが、「挿入または更新」ロジックはそれらを縮小セットに切り詰めます。メモリが少ないと例外などが発生する可能性がありますが、この種のデータは失われます。

于 2012-04-15T03:25:44.783 に答える
0

CSV ファイルに問題があると思われます。

私のおすすめ:

  • CSV から読み取った各行のデバッグ情報を出力します。これにより、処理された行数が表示されます。
  • 挿入/更新のたびに、エラーを出力します (存在する場合)

それは次のようなものです:

<?php
$csv = fopen('sample.csv', 'r'); $line = 1;
while (($item = fgetcsv($csv)) !== false) {
    echo 'Line ' . $line++ . '... ';

    $sql = ''; // your SQL query
    mysql_query($sql);
    $error = mysql_error();

    if ($error == '') {
        echo 'OK' . PHP_EOL;
    } else {
        echo 'FAILED' . PHP_EOL . $error . PHP_EOL;
    }
}

したがって、エラーがあれば、それを見て問題を見つけることができます (CSV のどの行に問題があるか)。

于 2012-04-18T13:32:56.537 に答える