500.000 行から 4.000.000 行までをインポートする次のコード (多かれ少なかれ) があります。
$sSql = "Insert into table (a,b,c) VALUES(?,?,?)"
$oSQLStmnt = $pdo->prepare($sSql);
$oSQLStmnt->setAttribute(PDO::SQLSRV_ATTR_ENCODING, PDO::SQLSRV_ENCODING_SYSTEM);
if (!$oSQLStmnt) {
echo $pdo->errorInfo(); // Handle errors
}
$pdo->beginTransaction();
$iLineCounter = 1;
while (($sLine = fgets ($oCSV, 8000)) !== FALSE) {
$aLine = explode('|', $sLine); //Fgetscsv did not work properly
if ($iLineCounter % 100 == 0) {
lo("Inserting row " . $iLineCounter);
$pdo->commit();
sleep(0.15);
$pdo->beginTransaction();
}
try {
$oSQLStmnt->execute($aLine);
$iSuccesulInserts++;
}
catch (exception $e) {
print_r($e);
$iFailedInserts++;
}
$iLineCounter++;
}
$pdo->commit();
ご覧のとおり、100 行ごとにコミットを実行し、スリープも追加しました。以前は 25,000 行ごとに 1 回だけコミットを実行していましたが、スリープは使用しませんでした。しかし、ある時点で、レコードが欠落していることに気付きました。これらの設定(スリープと行数)をいじり始めました。この方法で、欠落しているレコードの数を 50.000 から約 100 に減らしました。しかし、まだ欠落しているレコードがあります。彼らはどこへ行くの?何か問題があるとすぐにエラーを受け取るので、SQL が問題ないことはわかっています。
トランザクション中に多くの挿入をスタックできると思いましたか? beginTransaction の呼び出しが問題になる可能性はありますか?
アップデート:
報奨金は終了し、私はそれを授与しなければなりませんでした。回答ありがとうございます。または実際のヒント、実際に私の質問に答えた人はいませんでした。あなたの提案は大歓迎ですが、私は回避策を求めていませんでした。賞金が授与された答えは、実際に私の質問に答えるのに最も近かったためです。残念ながらうまくいきませんでした。
今のところ、CSV 一括インポートを使用していますが、問題なく動作しますが、この問題を解決するためのヒントが他にある場合はお知らせください。私は自分のオリジナルの方法を使用することを好みます。