PHP-скрипт с тайм-аутом запроса MySQL
У меня проблемы с запуском скрипта PHP, который вставляет данные в MySQL. Я получаю ошибку " 504 Gateway Time-out nginx " Когда страница PHP застревает с этим таймаутом, в базу данных было введено 10,102 строки данных. Я планирую вставить 160000 строк в одну загрузку скрипта.
Я сделал свой код более эффективным, используя подготовленный оператор для SQL. SQL также настроен в этой структуре:
INSERT INTO tbl_name (a,b,c) VALUES(1,2,3),(4,5,6),(7,8,9);
Я прочитал тайм- ауты SO PHP-скрипта и Как предотвратить тайм-аут php-скрипта из-за длинного запроса MySQL
Я попытался добавить в начало моего кода, но, похоже, ничего не изменилось:
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 и ищу руководство по этой проблеме.
2 ответа
set_time_limit(0);
сбрасывает счет, когда он выполняется. Это не меняет max_execution_time
в php.ini
так что для того, чтобы он имел какой-либо полезный эффект, вы должны запустить его в цикле.
// 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();
Конечно, вы можете поиграть со значением 5000, поэтому он выполняет сброс реже.
Из руководства:
При вызове set_time_limit() сбрасывает счетчик тайм-аута с нуля. Другими словами, если время ожидания составляет 30 секунд по умолчанию и 25 секунд на выполнение сценария выполняется вызов, такой как set_time_limit(20), сценарий будет работать в общей сложности 45 секунд до истечения времени ожидания.
Если вы используете запрос внутри цикла с таким большим количеством строк, он наверняка застрянет.
Лучший способ, который я могу предложить, - это просто обработать все данные, которые нужно вставить в строку PHP, а затем запустить один запрос для вставки данных.
Позвольте мне уточнить
$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...
Затем запустите запрос
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')
Примечание: в моем коде может быть какая-то синтаксическая ошибка, но здесь вы понимаете логику.