2017-05-03 56 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') 

注: 有可能是在我的代碼中的一些語法錯誤,但你在這裏得到的邏輯。