2017-05-03 10 views
0

MySQLにデータを挿入するPHPスクリプトの実行に問題があります。私が得たエラーは "504 Gateway Time-out nginx"です。このタイムアウトでPHPページが立ち往生すると、10,102行のデータがデータベースに入力されました。スクリプトの1回の読み込みに160,000行を挿入する予定です。MySQLクエリのタイムアウトを伴うPHPスクリプト

私は、SQL用に準備されたステートメントを使用することでコードをより効率的にしました。私は自分のコードの先頭に追加しようとしているSO PHP script times outHow to keep a php script from timing out because of a long mysql query

を読んだことがあるが、違いを確認していないよう

INSERT INTO tbl_name (a,b,c) VALUES(1,2,3),(4,5,6),(7,8,9); 

: SQLもこの構造体に設定されている

set_time_limit(0); 
ignore_user_abort(1); 

データセットを分割してチャンクに分割し、チャンクごとにデータを挿入することはできますか?

私は、私は、MySQLと協力し、この問題を持ついくつかのガイダンスを探していますに新しいです

// prepare and bind 
$stmt = $link->prepare("INSERT INTO MyGuests (`eventID`,`location`,`date`,`barcode`,`runner`,`time`,`Run Points`,`Volunteer Points`,`Gender`, `Gender pos`) VALUES (?,?,?,?,?,?,?,?,?,?)"); 
$stmt->bind_param("isssssiisi", $eventID,$location,$date,$barcode,$runner,$time,$runpoints,$volpoints,$gender,$genderpos); 

// set parameters and execute 
for($x=0; $x < count($array_runner); $x++){ 
    $eventID=null; 
    $barcode=$array_barcode[$x]; 
    $runner=$array_runner[$x]; 
    $time=$array_time[$x]; 
    $runpoints=$array_score[$x]; 
    $volpoints=' '; 
    $gender=$array_gender[$x]; 
    $genderpos=$array_gender_pos[$x]; 

    $stmt->execute(); 

} 

$stmt->close(); 
$link->close(); 

の下にMySQLへの挿入コードのセクションが表示されます。

+0

あなたはPHPの時間制限を変更する権利がないと思います。この場合、この問題をこのように解決する機会はありません。あなたのSQLクエリを分割した部分に分割することができます – Peter

+0

このスクリプトは、PHPのCLIとして、つまりコマンドラインから実行できますか? CLIに適用される 'max_execution_time'はありません。 – RiggsFolly

+0

コメントPeterに感謝します。ああ「権利なし」は迷惑ですが、このプロジェクトは共有サーバー上のiPageでのみホストされており、専用サーバー/ VPSを使用する予定はありません。 SQLを分割して分割するコードを提供できますか? – Jeanclaude

答えて

1

set_time_limit(0);は、実行時にカウントをリセットします。 php.inimax_execution_timeは変更されていないので、ループ内で実行すると効果があります。あなたはそれがあまり頻繁にリセットされない値5000で遊ぶことができます。もちろん、

// prepare and bind 
$stmt = $link->prepare("INSERT INTO MyGuests (`eventID`,`location`,`date`,`barcode`,`runner`,`time`,`Run Points`,`Volunteer Points`,`Gender`, `Gender pos`) VALUES (?,?,?,?,?,?,?,?,?,?)"); 
$stmt->bind_param("isssssiisi", $eventID,$location,$date,$barcode,$runner,$time,$runpoints,$volpoints,$gender,$genderpos); 

// set parameters and execute 
for($x=0; $x < count($array_runner); $x++){ 
    $eventID=null; 
    $barcode=$array_barcode[$x]; 
    $runner=$array_runner[$x]; 
    $time=$array_time[$x]; 
    $runpoints=$array_score[$x]; 
    $volpoints=' '; 
    $gender=$array_gender[$x]; 
    $genderpos=$array_gender_pos[$x]; 

    $stmt->execute(); 

    // every 5000 times through the loop reset the timeout 
    if ($x % 5000 == 0) { 
     set_time_limit(30); 
    } 
} 

$stmt->close(); 
$link->close(); 

。マニュアルから

呼ば

、をset_time_limit()は、ゼロからのタイムアウトカウンタを再起動します。つまり、タイムアウトがデフォルトの30秒で、スクリプトの実行にset_time_limit(20)などの呼び出しが25秒行われた場合、タイムアウトするまでにスクリプトは合計45秒間実行されます。

+0

set_time_limitは504とは何の関係もありません。ゲートウェイタイムアウト** nginx ** –

+0

@YourCommonSenseこれは、私が知る限り最大の実行時間を超過したために発生する可能性があります。私はそこに他の多くの理由もあると認めますが、 – RiggsFolly

+0

このコードに@RiggsFollyに感謝します。私はループ内でset_time_limit()を使用しようとしましたが、スクリプトはまだ10,102行のデータで止まっています。 – Jeanclaude

0

非常に多くの行数のループ内でクエリを使用している場合は、間違いなくスタックします。

私が提案できる最良の方法は、PHP文字列に挿入するすべてのデータを処理し、データを挿入するための単一のクエリを起動することです。 あり私のコードでは、いくつかの構文エラーことができますが、ここでロジックを取得する可能性があります:

は、私は、クエリ

mysqli_query("INSERT INTO MyGuests (`eventID`,`barcode`,`runner`) values" . $data_to_insert); 
// which would look like 
// INSERT INTO MyGuests (`eventID`,`barcode`,`runner`) values (eventid1 , 'barcode1', 'runner1'), (eventid2 , 'barcode2', 'runner2') 

注意を発射次に

$data_to_insert = '' // will contain all data to inserted 
$count = 1; 
$eventID = null; // if it is null for all rows 

for($x=0; $x < count($array_runner); $x++) 
{  
    if($count == 1) // checking if it is the first value to be inserted 
    { 
     $data_to_insert = "("; 
     $count = 2; 
    } 
    else // with second value onwards 
    { 
     $data_to_insert = ",(" ; 
    } 

    $data_to_insert = $data_to_insert . $eventID . ","; 
    $data_to_insert = $data_to_insert . "'". $barcode . "'"; 
    $data_to_insert = $data_to_insert . "'". $array_runner[$x] . "'"; 
    $data_to_insert = ")"; 
} 
// so in the last $data_to_insert should look like this 
// $data_to_insert = (eventid1 , 'barcode1', 'runner1'), (eventid2 , 'barcode2', 'runner2') and so on... 

を詳しく説明しましょう。

関連する問題