Changeset 19523


Ignore:
Timestamp:
2010/11/07 04:16:05 (12 years ago)
Author:
AMUAMU
Message:

商品一覧高速化と、IN句が長くなり正常に動かない問題を修正

Location:
branches/camp/camp-2_5-D/data/class
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/camp/camp-2_5-D/data/class/SC_Product.php

    r18882 r19523  
    4646    var $classCat2_find; 
    4747    var $classCats1; 
     48    /** 検索用並び替え条件配列 */ 
     49    var $arrOrderData; 
    4850 
    4951    /** 
     
    7274        return array_unique($resultValues); 
    7375    } 
     76     
     77    /** 
     78     * 商品検索結果の並び順を指定する。 
     79     * 
     80     * ただし指定できるテーブルはproduct_idを持っているテーブルであることが必要. 
     81     * 
     82     * @param string $col 並び替えの基準とするフィールド 
     83     * @param string $table 並び替えの基準とするフィールドがあるテーブル 
     84     * @param string $order 並び替えの順序 ASC / DESC 
     85     * @return void 
     86     */ 
     87    function setProductsOrder($col, $table = 'dtb_products', $order = 'ASC') { 
     88        $this->arrOrderData = array('col' => $col, 'table' => $table, 'order' => $order); 
     89    } 
     90 
     91    /** 
     92     * SC_Queryインスタンスに設定された検索条件を元に並び替え済みの検索結果商品IDの配列を取得する。 
     93     * 
     94     * 検索条件は, SC_Query::getWhere() 関数で設定しておく必要があります. 
     95     * 
     96     * @param SC_Query $objQuery SC_Query インスタンス 
     97     * @param array $arrVal 検索パラメータの配列 
     98     * @return array 商品IDの配列 
     99     */ 
     100    function findProductIdsOrder(&$objQuery, $arrVal = array(), $where) { 
     101        $table = <<< __EOS__ 
     102                 dtb_products AS alldtl 
     103            JOIN dtb_products_class AS T1 
     104              ON alldtl.product_id = T1.product_id 
     105            JOIN dtb_product_categories AS T2 
     106              ON alldtl.product_id = T2.product_id 
     107            JOIN dtb_category 
     108              ON T2.category_id = dtb_category.category_id 
     109__EOS__; 
     110        $objQuery->setGroupBy('alldtl.product_id'); 
     111        if(is_array($this->arrOrderData) and $objQuery->order == ""){ 
     112            $o_col = $this->arrOrderData['col']; 
     113            $o_table = $this->arrOrderData['table']; 
     114            $o_order = $this->arrOrderData['order']; 
     115            $order = <<< __EOS__ 
     116                    ( 
     117                        SELECT $o_col 
     118                        FROM 
     119                            $o_table as T2 
     120                        WHERE T2.product_id = alldtl.product_id 
     121                        ORDER BY T2.$o_col $o_order 
     122                        LIMIT 1 
     123                    ) $o_order, product_id 
     124__EOS__; 
     125            $objQuery->setOrder($order); 
     126        } 
     127        $results = $objQuery->select('alldtl.product_id', $table, "", $arrVal, 
     128                                     MDB2_FETCHMODE_ORDERED); 
     129        foreach ($results as $val) { 
     130            $resultValues[] = $val[0]; 
     131        } 
     132        return $resultValues; 
     133    } 
     134 
     135    /** 
     136     * SC_Queryインスタンスに設定された検索条件をもとに対象商品数を取得する. 
     137     * 
     138     * 検索条件は, SC_Query::getWhere() 関数で設定しておく必要があります. 
     139     * 
     140     * @param SC_Query $objQuery SC_Query インスタンス 
     141     * @param array $arrVal 検索パラメータの配列 
     142     * @return array 対象商品ID数 
     143     */ 
     144    function findProductCount(&$objQuery, $arrVal = array()) { 
     145        $table = <<< __EOS__ 
     146                 dtb_products AS alldtl 
     147            JOIN dtb_product_categories AS T2 
     148              ON alldtl.product_id = T2.product_id 
     149            JOIN dtb_category 
     150              ON T2.category_id = dtb_category.category_id 
     151__EOS__; 
     152        $objQuery->setGroupBy('alldtl.product_id'); 
     153        $sql_base = $objQuery->getSql('alldtl.product_id',$table); 
     154        return $objQuery->getOne( "SELECT count(*) FROM ( $sql_base ) as t" , $arrVal); 
     155    } 
     156     
    74157 
    75158    /** 
     
    109192            ,update_date 
    110193__EOS__; 
    111         return $objQuery->select($col, $this->alldtlSQL($objQuery->where), 
     194        $res = $objQuery->select($col, $this->alldtlSQL($objQuery->where), 
    112195                                 "", $arrVal); 
     196        return $res; 
    113197    } 
    114198 
  • branches/camp/camp-2_5-D/data/class/pages/products/LC_Page_Products_List.php

    r18862 r19523  
    314314    /* 商品一覧の表示 */ 
    315315    function lfDispProductsList() { 
    316  
    317316        $objDb = new SC_Helper_DB_Ex(); 
    318317        $arrval = array(); 
     
    324323            list($where_category, $arrval_category) = $objDb->sfGetCatWhere($this->arrSearchData['category_id']); 
    325324        } 
    326  
    327325        // ▼対象商品IDの抽出 
    328326        // 商品検索条件の作成(未削除、表示) 
    329         $where = "del_flg = 0 AND status = 1 "; 
    330         $where1 = "alldtl.del_flg = 0 AND alldtl.status = 1 "; 
     327        $where = "alldtl.del_flg = 0 AND alldtl.status = 1 "; 
    331328 
    332329        // 在庫無し商品の非表示 
    333330        if (NOSTOCK_HIDDEN === true) { 
    334             $where .= ' AND (stock_max >= 1 OR stock_unlimited_max = 1)'; 
     331            $where .= ' AND (stock >= 1 OR stock_unlimited = 1)'; 
    335332        } 
    336333 
    337334        if (strlen($where_category) >= 1) { 
    338             $where.= " AND $where_category"; 
    339             $where1 .= " AND T2.$where_category"; 
     335            $where .= " AND T2.$where_category"; 
    340336            $arrval = array_merge($arrval, $arrval_category); 
    341337        } 
     
    351347        foreach ($names as $val) { 
    352348            if ( strlen($val) > 0 ) { 
    353                 $where .= " AND ( name ILIKE ? OR comment3 ILIKE ?) "; 
    354                 $where1 .= " AND ( alldtl.name ILIKE ? OR alldtl.comment3 ILIKE ?) "; 
     349                $where .= " AND ( alldtl.name ILIKE ? OR alldtl.comment3 ILIKE ?) "; 
    355350                $arrval[] = "%$val%"; 
    356351                $arrval[] = "%$val%"; 
     
    360355        // メーカーらのWHERE文字列取得 
    361356        if ($this->arrSearchData['maker_id']) { 
    362             $where .= " AND maker_id = ? "; 
    363             $where1 .= " AND alldtl.maker_id = ? "; 
     357            $where .= " AND alldtl.maker_id = ? "; 
    364358            $arrval[] = $this->arrSearchData['maker_id']; 
    365359        } 
    366  
    367         // 一覧表示する商品IDを取得 
     360  
     361        // 検索結果対象となる商品の数を取得 
    368362        $objQuery =& SC_Query::getSingletonInstance(); 
    369         $objQuery->setWhere($where1); 
     363        $objQuery->setWhere($where); 
    370364        $objProduct = new SC_Product(); 
    371         $arrProduct_id = $objProduct->findProductIds($objQuery, $arrval); 
    372  
    373         // 行数の取得 
    374         $linemax = count($arrProduct_id); 
    375  
     365        $linemax = $objProduct->findProductCount($objQuery, $arrval); 
    376366        $this->tpl_linemax = $linemax;   // 何件が該当しました。表示用 
    377367 
     
    385375        $startno = $this->objNavi->start_row;                 // 開始行 
    386376 
    387         // WHERE 句 
    388         $where = '0=0'; 
    389         if (is_array($arrProduct_id) && !empty($arrProduct_id)) { 
    390             $where .= ' AND product_id IN (' . implode(',', $arrProduct_id) . ')'; 
    391         } else { 
    392             // 一致させない 
    393             $where .= ' AND 0<>0'; 
    394         } 
    395  
     377        $objProduct = new SC_Product(); 
     378        $objQuery =& SC_Query::getSingletonInstance(); 
    396379        // 表示順序 
    397380        switch ($this->orderby) { 
    398  
    399             // 販売価格順 
     381            // 販売価格が安い順 
    400382            case 'price': 
    401                 $order = "price02_min, product_id"; 
     383                $objProduct->setProductsOrder('price02', 'dtb_products_class', 'ASC'); 
    402384                break; 
    403385 
    404386            // 新着順 
    405387            case 'date': 
    406                 $order = "create_date DESC, product_id"; 
     388                $objProduct->setProductsOrder('create_date', 'dtb_products', 'DESC'); 
    407389                break; 
    408390 
     
    439421                    ,product_id 
    440422__EOS__; 
     423                    $objQuery->setOrder($order); 
    441424                break; 
    442425        } 
    443  
    444426        // 取得範囲の指定(開始行番号、行数のセット) 
     427        $objQuery->setLimitOffset($this->disp_number, $startno) 
     428                 ->setWhere($where); 
     429 
     430         // 表示すべきIDとそのIDの並び順を一気に取得 
     431        $arrProduct_id = $objProduct->findProductIdsOrder($objQuery, array_merge($arrval, $arrval_order)); 
     432 
     433        // 取得した表示すべきIDだけを指定して情報を取得。 
     434        $where = ""; 
     435        if (is_array($arrProduct_id) && !empty($arrProduct_id)) { 
     436            $where = 'product_id IN (' . implode(',', $arrProduct_id) . ')'; 
     437        } else { 
     438            // 一致させない 
     439            $where = '0<>0'; 
     440        } 
    445441        $objQuery =& SC_Query::getSingletonInstance(); 
    446         $objQuery->setLimitOffset($this->disp_number, $startno) 
    447                  ->setOrder($order) 
    448                  ->setWhere($where); 
    449  
    450         // 検索結果の取得 
    451         $objProduct = new SC_Product(); 
    452         $this->arrProducts = $objProduct->lists($objQuery, $arrval_order); 
    453  
    454         $arrProductId = array(); 
    455         // 規格セレクトボックス設定 
    456         foreach ($this->arrProducts as $product) { 
    457             $arrProductId[] = $product['product_id']; 
     442        $objQuery->setWhere($where); 
     443        $arrProducts = $objProduct->lists($objQuery, $arrProduct_id); 
     444 
     445        //取得している並び順で並び替え 
     446        $arrProducts2 = array(); 
     447        foreach($arrProducts as $item) { 
     448            $arrProducts2[ $item['product_id'] ] = $item; 
     449        } 
     450        $this->arrProducts = array(); 
     451        foreach($arrProduct_id as $product_id) { 
     452            $this->arrProducts[] = $arrProducts2[$product_id]; 
    458453        } 
    459454 
    460455        // 規格を設定 
    461         $objProduct->setProductsClassByProductIds($arrProductId); 
     456        $objProduct->setProductsClassByProductIds($arrProduct_id); 
    462457 
    463458        // 規格1クラス名 
     
    480475 
    481476        // 商品ステータスを取得 
    482         $this->productStatus = $objProduct->getProductStatus($arrProductId); 
     477        $this->productStatus = $objProduct->getProductStatus($arrProduct_id); 
    483478 
    484479        $productsClassCategories = $objProduct->classCategories; 
Note: See TracChangeset for help on using the changeset viewer.