1

4 000 000 行をフェッチして変換し、別のテーブルに挿入する必要があります。言うまでもなく、300 000 ~ エントリの後にメモリ不足エラーが発生します。各ループの後、割り当てられたメモリは正確に 160 バイト増加します。mysql_unbuffered_query() の使用が可能であることはわかっていますが、別のクエリを実行する前にすべての結果行をフェッチする必要があり、メモリ不足のエラーが再び発生します。では、1 回の実行でこれを行う最善の方法は何ですか?

mysql_connect($host, $user, $password);
mysql_select_db($db);

$getOldData = mysql_query("
SELECT *
FROM players_online 
ORDER by id ASC
");
$numRows = mysql_num_rows($getOldData);

for ($i=0; $i < $numRows; $i++) { 
$oldData = mysql_fetch_assoc($getOldData);
$hour = explode(':', $oldData['hour']);
$quarters = $hour[0] * 4 + $hour[1] / 15;

$update = mysql_query("
    INSERT INTO players_online_2 (world_id, players_online, quarters_past_midnight, date)
    VALUES (
        '".$oldData['world_id']."', 
        '".$oldData['players_online']."', 
        '".$quarters."', 
        '".$oldData['date']."'
    )
    ON DUPLICATE KEY UPDATE
        world_id='".$oldData['world_id']."', 
        players_online='".$oldData['players_online']."', 
        quarters_past_midnight='".$quarters."', 
        date='".$oldData['date']."'
");

if (mysql_error()) {
    echo mysql_error();
    die();
}

echo memory_get_usage().PHP_EOL;

}

4

2 に答える 2

1

MySQL Workbenchでは、古いデータベースをエクスポートして、新しい場所にインポートできます。

とはいえ、これを PHP で実行したい場合は、テーブル全体を一度に返すべきではありません。と を使用LIMITOFFSETてクエリをページに分割し、一度に 1 ページずつ実行できます。このようなもの:

for ($i = 0; $i < $Limit; $i++)
{
  // SELECT * FROM players_online ORDER by id ASC LIMIT 1000 OFFSET ' . $i
}
于 2013-06-01T14:38:20.340 に答える