3

PHP と MySQL を使用して、膨大な XML から解析された何千ものデータをデータベース テーブルに挿入しています。私の問題は、すべてのデータをテーブルに挿入するのに時間がかかりすぎることです。挿入プロセスがグループごとになるように、データを小さなグループに分割する方法はありますか? たとえば、データを 100 ずつ処理するスクリプトをどのように設定できますか? これが私のコードです:

foreach($itemList as $key => $item){
     $download_records  = new DownloadRecords();
    //check first if the content exists
    if(!$download_records->selectRecordsFromCondition("WHERE Guid=".$guid."")){
         /* do an insert here */
    } else {
         /*do an update */
    }

}

*注: $itemList は約 62,000 で、まだ増え続けています。

4

3 に答える 3

3

for ループを使用していますか?

ただし、データを MySQL にロードする最も簡単なオプションは、LOAD DATA INFILEコマンドを使用することです。PHP を介してロードするファイルを作成し、別のプロセスを介して (または元のプロセスの最終ステップとして) MySQL にフィードすることができます。

ファイルを使用できない場合は、次の構文を使用します。

insert into table(col1, col2) VALUES (val1,val2), (val3,val4), (val5, val6)

したがって、実行する文の合計量を減らします。

編集:スニペットを考えると、MySQL のINSERT ... ON DUPLICATE KEY UPDATE構文の恩恵を受けることができるようで、データベースに作業を任せ、クエリの量を減らします。これは、テーブルに主キーまたは一意のインデックスがあることを前提としています。

100行ごとにDBをヒットするには、次のようなことができます(確認して、環境に合わせて修正してください)

$insertOrUpdateStatement1 = "INSERT INTO table (col1, col2) VALUES ";
$insertOrUpdateStatement2 = "ON DUPLICATE KEY UPDATE ";
$counter = 0;
$queries = array();

foreach($itemList as $key => $item){
    $val1 = escape($item->col1); //escape is a function that will make 
                                 //the input safe from SQL injection. 
                                 //Depends on how are you accessing the DB

    $val2 = escape($item->col2);

    $queries[] = $insertOrUpdateStatement1. 
    "('$val1','$val2')".$insertOrUpdateStatement2.
    "col1 = '$val1', col2 = '$val2'";

    $counter++;

    if ($counter % 100 == 0) {
        executeQueries($queries);
        $queries = array();
        $counter = 0;
    }
}

そして、executeQueries は配列を取得し、単一の複数クエリを送信します。

function executeQueries($queries) {
   $data = "";
     foreach ($queries as $query) {
        $data.=$query.";\n";
    }
    executeQuery($data);
}
于 2009-06-25T07:00:06.157 に答える
0

はい、あなたが期待することをしてください。

タイムアウトなどに達する可能性があると思われる場合は、Web アプリケーションからの一括挿入を試みるべきではありません。代わりに、ファイルをどこかにドロップして、デーモンまたは cron などを用意し、それを取得してバッチ ジョブを実行します (cron から実行する場合は、一度に 1 つのインスタンスのみが実行されることを確認してください)。

于 2009-06-25T06:58:13.370 に答える