私はMySQLテーブルで作業していますが、各行に1つの値を増やす必要があります。PHP MySQL - 6.5m行のパフォーマンスの問題を修正する
col型はvarchar
であり、整数または文字列(つまり、+1
)を含むことができます。テーブルタイプはMyISAM
です。
私はPHPでこれを試みた:
$adjust_by = 1;
foreach ($options as $option) {
$original_turnaround = $option['turnaround'];
$adjusted_turnaround = $option['turnaround'];
if (preg_match('/\+/i', $original_turnaround)) {
$tmp = intval($original_turnaround);
$tmp += $adjust_by;
$adjusted_turnaround = '+'.$tmp;
} else {
$adjusted_turnaround += $adjust_by;
}
if (!array_key_exists($option['optionid'], $adjusted)) {
$adjusted[$option['optionid']] = array();
}
$adjusted[$option['optionid']][] = array(
'original_turn' => $original_turnaround,
'adjusted_turn' => $adjusted_turnaround
);
}//end fe options
//update turnarounds:
if (!empty($adjusted)) {
foreach ($adjusted as $opt_id => $turnarounds) {
foreach ($turnarounds as $turn) {
$update = "UPDATE options SET turnaround = '".$turn['adjusted_turn']."' WHERE optionid = '".$opt_id."' and turnaround = '".$turn['original_turn']."'";
run_query($update);
}
}
}
このアプローチの重大なパフォーマンス上の問題がある明白な理由。私のローカル開発環境でこれを実行すると、多くのエラーが発生し、最終的にサーバーがクラッシュします。
私が考慮する必要がある別のことは、これが運用環境で実行されるときです。これはeコマースストア向けのもので、このようにデータベースをロックしたり、その他の問題を引き起こしたりするような膨大なアップデートはできません。私が発見した
一つの可能な解決策はこれです:Fastest way to update 120 Million records
しかし、別のテーブルを作成することは、それ自身の問題が付属しています。コードベースが良好な状態ではないので、類似のクエリがこのテーブルで複数の場所で実行されるため、このアプローチを有効にするために多数のクエリとファイルを変更する必要があります。
私のオプション(あれば)には何がありますか?
"これは実稼働環境で実行されるときに考慮する必要があります。これはeコマースストア用であり、データベースをロックするなどの巨大なアップデートやその他の問題を引き起こすことはできません。 MyISAMエンジンは、更新または挿入時にテーブルをロックします。テーブルをInnoDBエンジンに変換することを検討する必要があります。このエンジンはテーブルを更新または挿入でロックしません。 –
テーブルのインデックスが正しく設定されていますか?シンプルなインデックス作成では、これを十分にスピードアップすることができます。 – sagi
PHPで集中的なタスクを実行しないでください。最大限のタイムアウトの問題を抱えている可能性があります。また、PHPはCPU集約型タスク用に設計されていません。あなたはむしろタスクのためにpythonを使うことができます。 – user254153