以下の PHP スクリプトは現在、インスタンス ストレージと MySQL 用の SSD マウントを備えた c3.large EC2 インスタンスでホストされています。スクリプトが読み取るファイルは、インスタンス ストレージ デバイスの 1 つにあります。
スクリプトが最初に起動すると、予想どおり 100% で実行されますが、数時間後にスクリプトの速度が約 5% に低下し、最終的に MySQL 挿入が極端に遅くなります。
このプロセスを遅くしている原因について何か考えはありますか? IOPS の問題でしょうか?
$handle = fopen(TMP . 'zones/' . $destinationFile, 'r');
if ($handle) {
$x = 0;
$origin = '';
while (($line = fgets($handle)) !== false) {
$x = $x + 1;
$line = str_replace("\r", '', $line);
$line = str_replace("\n", '', $line);
if ($x > 61) {
$record = explode(' ', $line);
switch ($record[1]) {
case 'NS':
$domain = $record[0];
$nameserver = rtrim($record[2], '.');
if ($record[2] == $nameserver) {
$nameserver = $nameserver . '.' . $origin;
}
$domainId = $this->addDomain($domain, $origin);
$nameserverId = $this->addNameserver($nameserver);
$dnId = $this->addDomainNameserver($domainId, $nameserverId);
break;
case 'A':
echo 'Nameserver IP: ' . $record[2];
break;
}
} else {
if (strpos($line, '$ORIGIN') > -1) {
$origin = str_replace('$ORIGIN ', '', $line);
$origin = rtrim($origin, '.');
}
}
}
fclose($handle);
}
答え1
StackOverflow で質問したほうがいいでしょう... MySQL の挿入について言及していますが、質問に SQL コードが見当たりません。通常、データベースに大量のデータを挿入する場合:
1) 行ごとに 1 つのリクエストを実行しません。2) 定期的に COMMIT を実行します。そうしないと、DB はすべてのデータを一時バッファに保持する必要があります。3) ただし、すべての行を COMMIT することはコストがかかるため行ごとに COMMIT を実行することはなく、通常は数千行のバッチでデータを入力します。
また、MySQLや他のDBMSには、ファイルから大きなテーブルを取り込む方法があります(LOAD DATA
SQLでまたはmysqlimport
コマンド) を使用すると、スクリプトでその中間ファイルを作成し、MySQL を呼び出して一度に読み込むことができます。