Changeset 19037


Ignore:
Timestamp:
2010/11/06 21:30:13 (13 years ago)
Author:
AMUAMU
Message:

sfCategory_Countの高速化の試作

File:
1 edited

Legend:

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

    r18984 r19037  
    897897    /** 
    898898     * カテゴリ数の登録を行う. 
     899     *  
    899900     * 
    900901     * @param SC_Query $objQuery SC_Query インスタンス 
    901902     * @return void 
    902903     */ 
    903     function sfCategory_Count($objQuery){ 
     904    function sfCategory_Count($objQuery = NULL){ 
     905        $objProduct = new SC_Product(); 
     906         
     907        if($objQuery == NULL) { 
     908                $objQuery =& SC_Query::getSingletonInstance(); 
     909        } 
     910        $is_out_tarns = false; 
     911        //トランザクションの開始確認。開始していない場合は 
     912        if(!$objQuery->inTransaction()){ 
     913            //TODO: トランザクション制御を足す? (重い!) 
     914            //$objQuery->begin(); 
     915            $is_out_trans = false; 
     916        } 
     917 
     918        //共通のfrom/where文の構築 
     919        $sql_where = 'alldtl.del_flg = 0 AND alldtl.status = 1'; 
     920        // 在庫無し商品の非表示 
     921        if (NOSTOCK_HIDDEN === true) { 
     922            $sql_where_dtl = 'stock_max >= 1 OR stock_unlimited_max = 1'; 
     923            $from = $objProduct->alldtlSQL($sql_where_dtl); 
     924        }else{ 
     925            $from = " dtb_products as alldtl "; 
     926        } 
     927         
     928        //dtb_category_countの構成 
     929        // 各カテゴリに所属する商品の数を集計。集計対象には子カテゴリを含まない。 
     930        // 2.5で消える予定だったが復活させます。 
     931         
     932        //まずテーブル内容の元を取得 
     933        $arrCategoryCountOld = $objQuery->select('category_id,product_count','dtb_category_count'); 
    904934 
    905935        //テーブル内容の削除 
    906936        $objQuery->query("DELETE FROM dtb_category_count"); 
    907         $objQuery->query("DELETE FROM dtb_category_total_count"); 
    908  
    909         $sql_where .= 'alldtl.del_flg = 0 AND alldtl.status = 1'; 
    910         // 在庫無し商品の非表示 
    911         if (NOSTOCK_HIDDEN === true) { 
    912             $sql_where .= ' AND (alldtl.stock_max >= 1 OR alldtl.stock_unlimited_max = 1)'; 
    913         } 
    914  
    915         //子カテゴリ内の商品数を集計する 
    916  
    917         // カテゴリ情報を取得 
    918         $arrCat = $objQuery->select('category_id', 'dtb_category'); 
    919  
    920         $objProduct = new SC_Product(); 
    921  
    922         foreach ($arrCat as $row) { 
    923             $category_id = $row['category_id']; 
     937 
     938        //各カテゴリ内の商品数を数えて格納 
     939        // これは単純集計なので比較的軽い 
     940        $sql = <<< __EOS__ 
     941            INSERT INTO dtb_category_count(category_id, product_count, create_date) 
     942            SELECT T1.category_id, count(T2.category_id), now() 
     943            FROM dtb_category AS T1 
     944                LEFT JOIN dtb_product_categories AS T2 
     945                    ON T1.category_id = T2.category_id 
     946                LEFT JOIN $from 
     947                    ON T2.product_id = alldtl.product_id 
     948            WHERE $sql_where 
     949            GROUP BY T1.category_id, T2.category_id 
     950__EOS__; 
     951        $objQuery->query($sql); 
     952                 
     953        //dtb_category_total_countの構成 
     954        // 各カテゴリに所属する商品の数を集計。集計対象には子カテゴリを「含む」。         
     955        //差分を取得して、更新対象カテゴリだけを確認する。 
     956         
     957        //各カテゴリ毎のデータ値において以前との差を見る 
     958        $arrCategoryCountNew = $objQuery->select('category_id, product_count','dtb_category_count'); 
     959         
     960        //古いデータの構造入れ替え 
     961        $arrOld = array(); 
     962        foreach($arrCategoryCountOld as $item){ 
     963            $arrOld[$item['category_id']] = $item; 
     964        } 
     965        //新しいデータの構造入れ替え 
     966        $arrNew = array(); 
     967        foreach($arrCategoryCountNew as $item){ 
     968            $arrNew[$item['category_id']] = $item; 
     969        } 
     970        $arrDiffCategory_id = array(); 
     971        //新しいカテゴリ一覧から見て商品数が異なるデータが無いか確認 
     972        foreach($arrCategoryCountNew as $item){ 
     973            $category_id = $item['category_id']; 
     974            if($arrOld[$category_id]['product_count'] != $item['product_count']){ 
     975                $arrDiffCategory_id[] = $category_id; 
     976            } 
     977        } 
     978        //削除カテゴリを想定して、古いカテゴリ一覧から見て商品数が異なるデータが無いか確認。 
     979        foreach($arrCategoryCountOld as $item){ 
     980            $category_id = $item['category_id']; 
     981            if($arrNew[$category_id]['product_count'] != $item['product_count']){ 
     982                $arrDiffCategory_id[] = $category_id; 
     983            } 
     984        } 
     985         
     986        //対象IDが無ければ終了 
     987        if(count($arrDiffCategory_id) == 0){ 
     988            if($is_out_tarns){ 
     989                $objQuery->commit(); 
     990            } 
     991            return; 
     992        } 
     993 
     994        //差分対象カテゴリIDの重複を除去 
     995        $arrDiffCategory_id = array_unique($arrDiffCategory_id); 
     996        //差分があったIDとその親カテゴリIDのリストを取得する 
     997        $arrTgtCategory_id = array(); 
     998        foreach ($arrDiffCategory_id as $parent_category_id) { 
     999            $arrTgtCategory_id[] = $parent_category_id; 
     1000            $arrParentID = $this->sfGetParents($objQuery, 'dtb_category', 'parent_category_id', 'category_id', $parent_category_id); 
     1001            foreach($arrParentID as $pid) { 
     1002                $arrTgtCategory_id[] = $pid; 
     1003            } 
     1004        } 
     1005         
     1006        //重複を取り除く 
     1007        $arrTgtCategory_id = array_unique($arrTgtCategory_id); 
     1008 
     1009        //dtb_cateogry_total_count 集計処理開始 
     1010        //旧データの削除 
     1011        $objQuery->query("DELETE FROM dtb_category_total_count WHERE category_id in (" . implode(',',$arrTgtCategory_id) . ")"); 
     1012 
     1013        //カテゴリ毎に処理 
     1014        foreach ($arrTgtCategory_id as $category_id) { 
    9241015            $arrval = array(); 
    925  
    9261016            $arrval[] = $category_id; 
    927  
    9281017            list($tmp_where, $tmp_arrval) = $this->sfGetCatWhere($category_id); 
    9291018            if ($tmp_where != "") { 
     
    9451034               WHERE $where 
    9461035__EOS__; 
    947  
    9481036            $objQuery->query($sql, $arrval); 
     1037        } 
     1038        //トランザクションの終了処理。 
     1039        if($is_out_tarns){ 
     1040            $objQuery->commit(); 
    9491041        } 
    9501042    } 
Note: See TracChangeset for help on using the changeset viewer.