2013-11-27 59 views
0

我有一個PHP腳本,由jQuery .post調用,它將提交一個電子郵件地址列表,執行列表中的一些操作(刪除重複,排序,格式等),然後將每個存儲到MySQL數據庫中。慢PHP腳本格式化,排序,並從列表中刪除重複項

我遇到的問題是在大型列表上執行此操作需要很長時間。我正在測試一個15,000個電子郵件地址的列表,並在300秒(5分鐘)內,它只增加了大約5000個地址。

是否有我的代碼需要很長時間才能處理?這裏是。我知道我做了很多的格式,但這只是因爲一些電子郵件地址包含奇怪的字符等

// form posts 
$addresses = $_POST['email_addresses']; 

// cleanse and format 
$addresses = trim($addresses); 
$addresses = trim($addresses, "\xC2\xA0"); 
$addresses = str_replace(" ", "", $addresses); 
$addresses = preg_replace("/(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+/", "\n", $addresses); 
$addresses = str_replace("\n", ",", $addresses); 
$addresses = preg_replace('/[^(\x20-\x7F)]*/','', $addresses); 
$addresses = strtolower($addresses); 
$array_addresses = explode(",", $addresses); 

// get unique values 
$unique_addresses = array(); 
foreach($array_addresses as $key => $value) { 
    if(filter_var($value, FILTER_VALIDATE_EMAIL)){ 
     $unique_addresses[$value] = $value; 
    } 
} 

sort($unique_addresses); 

foreach($unique_addresses as $arr) { 

    if ($insert_addresses_stmt = $mysqli->prepare("INSERT INTO email_addresses (lid, email_addresses) VALUES (?, ?)")) { 

     $insert_addresses_stmt->bind_param("ss", $new_lid, $arr); 

     $insert_addresses_stmt->execute(); 

     $insert_addresses_stmt->close(); 

    } 
} 
+1

使用類似xdebug的分析器來找出代碼中的_what_很慢。但是,美元甜甜圈是_add每個地址到數據庫_這是放緩你的下降。 –

+0

第一部分看起來多餘,只使用過濾器就應該這樣做。除此之外,如果地址得到補充,瓶頸就在數據庫操作中。您應該批量添加地址,而不是逐個添加地址。 – jeroen

+0

你如何做數據庫插入?你是否在爲每個地址進行數據庫調用,或者你是否以某種方式對插入進行了批處理? –

回答

0

誠徵評論這一點,但不能做還。不管怎麼樣,純邏輯給了我一個線索,這樣一個巨大的多過濾/檢查/替換的帖子會對服務器CPU/RAM造成一些問題,並且會超載我經歷過的大量查詢所遇到的PHP內存......所以我們可以給它一些空閒空間。

你可以給這個(路)一個鏡頭。一個接一個地做(電子郵件)工作 - 而不是15k羣。等待約30秒完成這項工作。

// form posts 
$add = $_POST['email_addresses']; //15.000 emails in this I suppose 

//do walk in a park work first 
$add = trim($add, "\xC2\xA0"); 

//lets get emails one by one.. 
$addr = explode(",", $add); 
unset($add); //flush sufficient data 

    { 
    while (list($key,$add) = each($addr)) 
    { 

// cleanse and format 1by1 
$addresses = str_replace(' ', '', $add); 
$addresses = preg_replace("/(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+/", "\n", $addresses); 
$addresses = str_replace("\n", ",", $addresses); 
$addresses = preg_replace('/[^(\x20-\x7F)]*/','', $addresses); 

//finally lower chars 
$addresses = strtolower($addresses); 

//check email 
    if(filter_var($addresses, FILTER_VALIDATE_EMAIL)){ 
//do mysql query (first) if email already exists in your DB. if not... 
-> insert this email to DB 
    } 


} 
} 
//done 

當然,這個「辦法」做的沒有使用排序DB條目之前()函數,因爲這是1by1所在的插入,而不是在1個DB行(其中sort()是必不可少的)一個15K一堆插件。猜猜它是沒有必要的,因爲我們可以稍後繪製數據。