我在运行将脚本数据插入MySQL的PHP脚本时遇到问题。我得到的错误是“ 504 Gateway Time-out nginx ”当PHP页面遇到此超时时,已经向数据库输入了10,102行数据。我打算在一个脚本加载中插入160,000行。
通过使用SQL的预准备语句,我使代码更高效。 SQL也在此结构中设置:
INSERT INTO tbl_name (a,b,c) VALUES(1,2,3),(4,5,6),(7,8,9);
我看过SO PHP script times out和How to keep a php script from timing out because of a long mysql query
我尝试添加到代码的开头,但似乎没有什么区别:
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 :(得分:1)
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秒。
答案 1 :(得分:0)
如果你在一个行数如此之多的循环中使用查询,它肯定会卡住。
我建议的最好方法是简单地处理要插入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')
注意: 我的代码中可能存在一些语法错误,但您可以在此获得逻辑。