2017-05-03 116 views
0

我有问题运行PHP脚本插入数据到MySQL。我得到的错误是“504网关超时nginx”当PHP页面被这个超时卡住时,10,102行数据被输入到数据库中。我打算在脚本的一个负载中插入160,000行。PHP脚本与MySQL查询超时

我通过使用SQL的准备语句使我的代码更高效。 的SQL也都设立在这个结构:

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

我已阅读SO PHP script times outHow to keep a php script from timing out because of a long mysql query

我试图加入我的代码的开始,但似乎并没有发挥作用:

set_time_limit(0); 
ignore_user_abort(1); 

任何人都可以显示我的数据将数据集分割成chunnks和每个块数据插入?

我将展示的代码插入到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运行,即从命令行运行!没有'max_execution_time'应用于CLI – RiggsFolly

+0

感谢您的评论彼得。Ah“没有权限”很烦人,这个项目只在iPage上的共享服务器上运行,并且没有计划使用专用服务器/ VPS。你能否提供任何代码将分离的部分中的SQL分开? – Jeanclaude

回答

1

set_time_limit(0);重新执行计数。它不会更改php.ini中的max_execution_time,所以为了使其具有任何有用的效果,您必须在循环中运行它。

// 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秒。

+0

set_time_limit与504网关超时无关** nginx ** –

+0

@YourCommonSense唔,据我所知,它可能是由超过max_execution_time造成的!虽然我承认还有很多其他的原因 – RiggsFolly

+0

感谢@RiggsFolly这段代码,我已经尝试过在循环中使用set_time_limit(),但脚本仍然停留在10,102行数据。 – Jeanclaude

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') 

注: 有可能是在我的代码中的一些语法错误,但你在这里得到的逻辑。