2016-11-10 30 views
1

我有一個Android應用程序,它是一個虛擬商店。在foreach中優化SQL查詢()

在這個應用程序中,我做了一個查詢來填寫list --> category --> subcategory --> products。這裏的問題是foreach中的優化。

如何優化foreach?

Shop::setIdShop(Tools::getValue('boutique')); 
$cntxt = Context::getContext(); 
$cntxt->shop = new Shop(Tools::getValue('boutique')); 

$categorie = New Category(Tools::getValue('id_category')); 

    $result_product_count = Db::getInstance()->ExecuteS(' 
    SELECT COUNT(p.`id_product`) as totalProducts 
    FROM `'._DB_PREFIX_.'product` p , `'._DB_PREFIX_.'product_shop` ps 
    WHERE p.`active` = 1 
    AND p.`id_product` = ps.`id_product` 
    AND ps.`id_shop` = '.$cntxt->shop->id); 
    $count = $result_product_count[0]['totalProducts']; 



$promos = Product::getPricesDrop($id_lang = 1, $page_number = 0, $nb_products = $count, $count = false, 
$order_by = null, $order_way = null, $beginning = false, $ending = false, $context = $cntxt); 

$products = $categorie->getProducts($context->language->id,0,$result_product_count[0]['totalProducts'] , null ,null , false , $active = true, $random = false, $random_number_products = 1, $check_access = true, $context = $cntxt); 

$sql_gestion_stock = 'SELECT value FROM `ps_configuration` WHERE name="PS_STOCK_MANAGEMENT" AND id_shop="'.$cntxt->shop->id.'"'; 
$result_gestion_stock = Db::getInstance()->ExecuteS($sql_gestion_stock); 

$sql_order_stock = 'SELECT value FROM `ps_configuration` WHERE name="PS_ORDER_OUT_OF_STOCK" AND id_shop="'.$cntxt->shop->id.'"'; 
$result_order_stock = Db::getInstance()->ExecuteS($sql_order_stock); 

$resultat = array(); 
$row = array(); 


foreach($products as $p) 
{ 
    $prod = new Product($p['id_product']); 

    $order_out_of_stock = Configuration::get('PS_ORDER_OUT_OF_STOCK','','',$cntxt->shop->id); 
    $stock_management = Configuration::get('PS_STOCK_MANAGEMENT','','',$cntxt->shop->id); 
    $sql_stock = 'SELECT out_of_stock FROM ' ._DB_PREFIX_. 'stock_available WHERE id_product="'.$p['id_product'].'" AND id_shop="'.Tools::getValue('boutique').'"'; 
    $out_of_stock = Db::getInstance()->ExecuteS($sql_stock); 
    $stock_dispo = $out_of_stock[0]['out_of_stock']; 

    if($stock_management == 0){ 
     $qty = 9999; 
     $out_of_stock_mobile = 1; 
    } 
    else{ 
     if($stock_dispo == 0){ 
      $qty = $prod->getRealQuantity($p['id_product'],0,0,Tools::getValue("boutique")); 
      $out_of_stock_mobile = 0; 
     } 
     elseif($stock_dispo == 1){ 
      $qty = 9999; 
      $out_of_stock_mobile = 1; 
     } 
     elseif($stock_dispo == 2){ 
      if($order_out_of_stock == 1){ 
       $qty = 9999; 
       $out_of_stock_mobile = 1; 
      } 
      else{ 
       $qty = $prod->getRealQuantity($p['id_product'],0,0,Tools::getValue("boutique")); 
       $out_of_stock_mobile = 0; 
      } 
     } 
    } 

    $link = New Link(); 
    $img=''; 
    $imgLink = ''; 
    if (count($prod->getImages($cntxt->language->id ,$context = $cntxt))>0) { 
    $imgCover = Product::getCover($prod->id, $context = $cntxt); 
    $imgLink = $link->getImageLink($prod->link_rewrite[1] , $imgCover["id_image"] , 'medium_default'); 
    $imgLink = 'http://'.$imgLink; 
    $largeImgLink = $link->getImageLink($prod->link_rewrite[1] , $imgCover["id_image"] , 'large_default'); 
    $largeImgLink = 'http://'.$largeImgLink; 
    } 
    $row['hasSold']= 0; 
    if (count(promos)>0) { 
     foreach($promos as $promo) 
     { 

      if ($promo['id_product'] == $p['id_product']) { 
      $rowProd = array('id_product' => $p['id_product'],'out_of_stock' => $prod->out_of_stock); 
      $productProp = $prod->getProductProperties($id_lang = 1 , $rowProd , $context = $cntxt); 
      $now = time(); 
      $date1 = strtotime($productProp["specific_prices"]["to"]); 
      $diff = abs($date1 - $now); 
      $tmp = $diff; 
      $retour = array(); 
       $retour['second'] = $tmp % 60; 

       $tmp = floor(($tmp - $retour['second']) /60); 
       $retour['minute'] = $tmp % 60; 

       $tmp = floor(($tmp - $retour['minute'])/60); 
       $retour['hour'] = $tmp % 24; 

       $tmp = floor(($tmp - $retour['hour']) /24); 
       $retour['day'] = $tmp; 
      $row['hasSold']= 1; 
      $row['temps_restant']= $retour['day'].'j '.$retour['hour'].':'.$retour['minute'].':'.$retour['second']; 
      } 

     } 
    } 


    $row['image']= $imgLink; 
    $row['titre']=$prod->name["1"]; 
    $row['description']=strip_tags($prod->description["1"]); 
    $row['largeImage']= $largeImgLink; 
    $images = $prod->getImages((int)$cntxt->language->id); 
    $imagesmeduim=array(); 
    $imageslarge=array(); 
    $j=0; 
    foreach($images as $i) 
    { 
     if (!$i['cover']) 
     { 
     $imgLink_list = $link->getImageLink($prod->link_rewrite[1] , $i["id_image"] , 'medium_default'); 
     $largeImgLink_list = $link->getImageLink($prod->link_rewrite[1] , $i["id_image"] , 'large_default'); 
     $imagesmeduim[$j]=$imgLink_list; 
     $imageslarge[$j]=$largeImgLink_list; 
     $j++; 
     } 
    } 


    $row['qty']= $qty; 
    $row['out_of_stock'] = $out_of_stock_mobile; 
    $row['id_product']=$p['id_product']; 
    $row['sous_titre']=strip_tags($prod->description_short["1"]); 
    $row['prix_promotion']= (string)$prod->getPrice(true,NULL,2); 
    $row['prix_orig']= Tools::ps_round((string)$prod->getPriceWithoutReduct(), 2); 
    foreach ($row as $key => $value) { 
     if ($value == NULL) { 
      $row[$key]=''; 
     } 
    } 
    $row['images_meduim']= $imagesmeduim;  
    $row['images_large']= $imageslarge; 
    $resultat[]=$row; 
} 

echo json_encode($resultat); 

}

回答

1

我認爲你有沒有在你的SQL查詢中使用兩個表的語句,並使用內部連接,因爲它的速度更快就像

SELECT COUNT(p.`id_product`) as totalProducts 
    FROM `'._DB_PREFIX_.'product` p 
    inner join `'._DB_PREFIX_.'product_shop` ps 
    on p.`id_product` = ps.`id_product` 
    WHERE p.`active` = 1 
    AND ps.`id_shop` = '.$cntxt->shop->id); 

,我不明白你爲什麼使用這個

$order_out_of_stock = Configuration::get('PS_ORDER_OUT_OF_STOCK','','',$cntxt->shop->id); 
$stock_management = Configuration::get('PS_STOCK_MANAGEMENT','','',$cntxt->shop->id); 

在foreach,它會做所有的時間相同,所以也許喲你應該這樣做嗎?

---- ----編輯

因此,也許你可以做一些其他的東西一樣不使用foreach爲您的促銷

if(isset($promo[$p['id_product']]) 
{ 
    $rowProd = array('i..... 

,而不是

if (count(promos)>0) { 
    foreach($promos as $promo) 
{ 
    if ($promo['id_product'] == $p['id_product']) { 

但是,如果你真的得到了很多數據和行動,我不確定服務器速度變化的任何想法。

+0

嗨,謝謝你的回答。我更新我的代碼,對不起。 –

+0

我有34個類別和1500個產品。 通常我填寫32個分組的列表。內連接28分段。 問題與foreach或服務器速度有問題嗎? 再次感謝 –

+0

你是法國人嗎? – MacBooc