簡體   English   中英

從CSV用PHP更新MySQL時超時

[英]Timing out while updating MySQL with PHP from a CSV

我需要想出一種方法來使大型任務更快地克服超時。

由於托管公司的限制,我對服務器的訪問非常有限。

我有一個系統設置,其中cron訪問一個PHP文件,該文件捕獲包含某些產品數據的csv。 csv並不包含產品具有的所有字段。 只是一些必要的。

我已經閱讀了很多有關超時和處理csv的文章,並且目前(為了節省時間),我已經制作了一個表(稱為csv_data)來保存csv數據。 我有一個腳本,該腳本會截斷csv_data表,然后從csv插入數據,因此每天晚上csv的最新記錄集都在該表中(csv文件每晚更新一次)。 到目前為止,沒有超時問題。該任務僅需4-5秒。

當我必須篩選數據以更新產品表時,會發生超時。 它現在正在運行的步驟是這樣的

1. Get the sku from csv_data table (that holds thousands of records)
2. Select * from Products where products.sku = csv.sku (products table also holds thousands of records to loop through)
3. Get numrows.   
    If numrows<0{no record in products, so skip}. 
    If numrows>1{duplicate entries, don't change anything, but later on report the sku}
    If numrows==1{Update selected fields in the products table with csv data}
4. Go to the next record in csv_data all over again

(我發現概述該過程比放入代碼中更短,更容易。)我研究了MySQl視圖和存儲過程,但我並不熟練,無法知道它是否會處理'if'語句部分。

我有什么可以做的更快地避免超時?

編輯:

我應該提到set_time_limit(0); 沒有這樣做。 如果有幫助,則服務器使用IIS7fastcgi謝謝您的幫助。

使用Jakob和Shawn的建議后進行更新:

我做錯了。 速度肯定更快,並且csv sku正在增加,

但是當我嘗試實現肖恩的解決方案時; 查詢給我一個PHP警告:mysql_result()期望參數1為資源,布爾錯誤。

您能幫我發現我做錯了什么嗎?

這是代碼部分:

$csvdata="SELECT * FROM csv_update";
    $csvdata_result=mysql_query($csvdata); 
    mysql_query($csvdata);
    $csvdata_num = mysql_num_rows($csvdata_result);
    $i=0;       
while($i<$csvdata_num){

$csv_code=@mysql_result($csvdata_result,$i,"skucode");

$datacheck=NULL;    
$datacheck=substr($csv_code,0,1);

if($datacheck>='0' && $datacheck<='9'){

$csv_price=@mysql_result($csvdata_result,$i,"price");
$csv_retail=@mysql_result($csvdata_result,$i,"retail");
$csv_stock=@mysql_result($csvdata_result,$i,"stock");
$csv_weight=@mysql_result($csvdata_result,$i,"weight");
$csv_manufacturer=@mysql_result($csvdata_result,$i,"manufacturer");
$csv_misc1=@mysql_result($csvdata_result,$i,"misc1");
$csv_misc2=@mysql_result($csvdata_result,$i,"misc2");
$csv_selectlist=@mysql_result($csvdata_result,$i,"selectlist");
$csv_level5=@mysql_result($csvdata_result,$i,"level5");
$csv_frontpage=@mysql_result($csvdata_result,$i,"frontpage");
$csv_level3=@mysql_result($csvdata_result,$i,"level3");
$csv_minquantity=@mysql_result($csvdata_result,$i,"minquantity");
$csv_quantity1=@mysql_result($csvdata_result,$i,"quantity1");
$csv_discount1=@mysql_result($csvdata_result,$i,"discount1");
$csv_quantity2=@mysql_result($csvdata_result,$i,"quantity2");
$csv_discount2=@mysql_result($csvdata_result,$i,"discount2");
$csv_quantity3=@mysql_result($csvdata_result,$i,"quantity3");
$csv_discount3=@mysql_result($csvdata_result,$i,"discount3");

    $count_check="SELECT COUNT(*) AS totalCount FROM products WHERE skucode = '$csv_code'";
    $count_result=mysql_query($count_check); 
    mysql_query($count_check);
    $totalCount=@mysql_result($count_result,0,'totalCount');
    $loopCount = ceil($totalCount / 25);
    for($j = 0; $j < $loopCount; $j++){

    $prod_check="SELECT skucode FROM products WHERE skucode = '$csv_code' LIMIT ($loopCount*25), 25;";
    $prodresult=mysql_query($prod_check); 
    mysql_query($prod_check);
    $prodnum =@mysql_num_rows($prodresult);
    $prod_id=@mysql_result($prodresult,0,"catalogid");


    if($prodnum<1){ 
    echo "NOT FOUND:$csv_code<br>";
    $count_sku_not_found=$count_sku_not_found+1;
    $list_sku_not_found=$list_sku_not_found." $csv_code";}

    if($prodnum>1){ 
    echo "DUPLICATE:$csv_ccode<br>";    
    $count_duplicate_skus=$count_duplicate_skus+1;
    $list_duplicate_skus=$list_duplicate_skus." $csv_code";}


if ($prodnum==1){
///This prevents an overwrite from happening if the csv file doesn't produce properly
    if ($csv_price!="" OR $csv_price!=NULL)
    {$sql_price='price="'.$csv_price.'"';}

    if ($csv_retail!="" OR $csv_retail!=NULL)
    {$sql_retail=',retail="'.$csv_retail.'"';}

    if ($csv_stock!="" OR $csv_stock!=NULL)
    {$sql_stock=',stock="'.$csv_stock.'"';}

    if ($csv_weight!="" OR $csv_weight!=NULL)
    {$sql_weight=',weight="'.$csv_weight.'"';}

    if ($csv_manufacturer!="" OR $csv_manufacturer!=NULL)
    {$sql_manufacturer=',manufacturer="'.$csv_manufacturer.'"';}

    if ($csv_misc1!="" OR $csv_misc1!=NULL)
    {$sql_misc1=',misc1="'.$csv_misc1.'"';}

    if ($csv_misc2!="" OR $csv_misc2!=NULL)
    {$sql_pother2=',pother2="'.$csv_misc2.'"';}

    if ($csv_selectlist!="" OR $csv_selectlist!=NULL)
    {$sql_selectlist=',selectlist="'.$csv_selectlist.'"';}

    if ($csv_level5!="" OR $csv_level5!=NULL)
    {$sql_level5=',level5="'.$csv_level5.'"';}

    if ($csv_frontpage!="" OR $csv_frontpage!=NULL)
    {$sql_frontpage=',frontpage="'.$csv_frontpage.'"';}



$import="UPDATE products SET $sql_price $sql_retail $sql_stock $sql_weight $sql_manufacturer $sql_misc1 $sql_misc2 $sql_selectlist $sql_level5 $sql_frontpage    $sql_in_stock WHERE skucode='$csv_code'";
 mysql_query($import) or die(mysql_error("error updating in products table"));


echo "Update ".$csv_code." successful ($i)<br>";

$count_success_update_skus=$count_success_update_skus+1;
$list_success_update_skus=$list_success_update_skus." $csv_code";



//empty out variables 
$sql_price='';
$sql_retail='';
$sql_stock='';
$sql_weight='';
$sql_manufacturer='';
$sql_misc1='';
$sql_misc2='';
$sql_selectlist='';
$sql_level5='';
$sql_frontpage='';
$sql_in_stock='';
$prodnum=0;

}
}
$i++;
}

是在返回第一行之前超時還是在讀取期間在行之間? 好的做法之一是分批處理您的查詢; 首先做一個計數,以查看您正在為SKU處理多少記錄,即通過較小的塊進行循環(這些塊的大小取決於每行要執行的操作數)。 您更新后的工作流程將如下所示:

  1. 從CSV獲取下一個SKU
  2. 獲取總數: SELECT COUNT(*) AS totalCount FROM products WHERE products.sku = csv.sku
  3. 確定塊大小(此演示使用25)
  4. loopCount = ceil(totalCount / 25)
  5. 使用這樣的循環遍歷所有結果: for($i = 0; $i < loopCount; $i++)
  6. 在循環內部,您應該運行如下查詢: SELECT * FROM products WHERE products.sku = csv.sku LIMIT (loopCount*25), 25

您將要為SELECT塊使用恆定順序; 您的唯一ID可能是最好的。

我認為您可以使用cron解決此問題。 http://en.wikipedia.org/wiki/Cron 它從未超時。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM