在foreach()中优化SQL查询

时间:2016-11-10 14:31:40

标签: php android foreach

我有一个Android应用程序,它是一个虚拟商店。

在这个应用程序中,我提出了一个查询来填充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 个答案:

答案 0 :(得分:1)

我认为你不得在SQL查询的from语句中使用两个表并使用内连接,因为它更快

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中做到这一点?

---- ---- EDIT

所以也许你可以做一些其他事情,比如不要用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']) {

但是如果你真的得到了很多数据和动作,我不确定服务器速度是否会发生变化。