Changeset 19691


Ignore:
Timestamp:
2010/11/30 03:00:48 (13 years ago)
Author:
AMUAMU
Message:

#781 sfCategory_Countのさらなる高速化(規格のデータベースを木構造に)
#799 SC_Helper_DB#sfCategory_Count をトランザクションブロックで実行する の解決。

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/version-2_5-dev/data/class/helper/SC_Helper_DB.php

    r19688 r19691  
    923923     * 
    924924     * @param SC_Query $objQuery SC_Query インスタンス 
     925     * @param boolean $is_force_all_count 全カテゴリの集計を強制する場合 true 
    925926     * @return void 
    926927     */ 
    927     function sfCategory_Count($objQuery = NULL){ 
     928    function sfCategory_Count($objQuery = NULL, $is_force_all_count = false){ 
    928929        $objProduct = new SC_Product(); 
    929930         
    930931        if($objQuery == NULL) { 
    931                 $objQuery =& SC_Query::getSingletonInstance(); 
    932         } 
    933         $is_out_tarns = false; 
    934         //トランザクションの開始確認。開始していない場合は 
     932            $objQuery =& SC_Query::getSingletonInstance(); 
     933        } 
     934         
     935        $is_out_trans = false; 
    935936        if(!$objQuery->inTransaction()){ 
    936             //TODO: トランザクション制御を足す? (重い!) 
    937             //$objQuery->begin(); 
    938             $is_out_trans = false; 
    939         } 
    940  
     937            $objQuery->begin(); 
     938            $is_out_trans = true; 
     939        } 
     940         
    941941        //共通のfrom/where文の構築 
    942942        $sql_where = 'alldtl.del_flg = 0 AND alldtl.status = 1'; 
     
    951951        //dtb_category_countの構成 
    952952        // 各カテゴリに所属する商品の数を集計。集計対象には子カテゴリを含まない。 
    953         // 2.5で消える予定だったが復活させます。 
     953        // 2.5で消える予定だったが復活させます。DELETE処理は無くしました。 
    954954         
    955955        //まずテーブル内容の元を取得 
    956         $arrCategoryCountOld = $objQuery->select('category_id,product_count','dtb_category_count'); 
    957  
    958         //テーブル内容の削除 
    959         $objQuery->query("DELETE FROM dtb_category_count"); 
    960  
    961         //各カテゴリ内の商品数を数えて格納 
    962         // これは単純集計なので比較的軽い 
     956        if(!$is_force_all_count) { 
     957            $arrCategoryCountOld = $objQuery->select('category_id,product_count','dtb_category_count'); 
     958        }else{ 
     959            $arrCategoryCountOld = array(); 
     960        } 
     961 
     962        //各カテゴリ内の商品数を数えて取得 
    963963        $sql = <<< __EOS__ 
    964             INSERT INTO dtb_category_count(category_id, product_count, create_date) 
    965             SELECT T1.category_id, count(T2.category_id), now() 
     964            SELECT T1.category_id, count(T2.category_id) as product_count 
    966965            FROM dtb_category AS T1 
    967966                LEFT JOIN dtb_product_categories AS T2 
     
    972971            GROUP BY T1.category_id, T2.category_id 
    973972__EOS__; 
    974         $objQuery->query($sql); 
    975                  
    976         //dtb_category_total_countの構成 
     973 
     974        $arrCategoryCountNew = $objQuery->getAll($sql); 
    977975        // 各カテゴリに所属する商品の数を集計。集計対象には子カテゴリを「含む」。         
    978976        //差分を取得して、更新対象カテゴリだけを確認する。 
    979          
    980         //各カテゴリ毎のデータ値において以前との差を見る 
    981         $arrCategoryCountNew = $objQuery->select('category_id, product_count','dtb_category_count'); 
    982          
     977 
     978        //各カテゴリ毎のデータ値において以前との差を見る         
    983979        //古いデータの構造入れ替え 
    984980        $arrOld = array(); 
    985981        foreach($arrCategoryCountOld as $item){ 
    986             $arrOld[$item['category_id']] = $item; 
     982            $arrOld[$item['category_id']] = $item['product_count']; 
    987983        } 
    988984        //新しいデータの構造入れ替え 
    989985        $arrNew = array(); 
    990986        foreach($arrCategoryCountNew as $item){ 
    991             $arrNew[$item['category_id']] = $item; 
    992         } 
     987            $arrNew[$item['category_id']] = $item['product_count']; 
     988        } 
     989 
    993990        $arrDiffCategory_id = array(); 
    994991        //新しいカテゴリ一覧から見て商品数が異なるデータが無いか確認 
    995         foreach($arrCategoryCountNew as $item){ 
    996             $category_id = $item['category_id']; 
    997             if($arrOld[$category_id]['product_count'] != $item['product_count']){ 
    998                 $arrDiffCategory_id[] = $category_id; 
     992        foreach($arrNew as $cid => $count){ 
     993            if($arrOld[$cid] != $count){ 
     994                $arrDiffCategory_id[] = $cid; 
    999995            } 
    1000996        } 
    1001997        //削除カテゴリを想定して、古いカテゴリ一覧から見て商品数が異なるデータが無いか確認。 
    1002         foreach($arrCategoryCountOld as $item){ 
    1003             $category_id = $item['category_id']; 
    1004             if($arrNew[$category_id]['product_count'] != $item['product_count']){ 
    1005                 $arrDiffCategory_id[] = $category_id; 
     998        foreach($arrOld as $cid => $count){ 
     999            if($arrNew[$cid] != $count){ 
     1000                $arrDiffCategory_id[] = $cid; 
    10061001            } 
    10071002        } 
     
    10091004        //対象IDが無ければ終了 
    10101005        if(count($arrDiffCategory_id) == 0){ 
    1011             if($is_out_tarns){ 
     1006            if($is_out_trans) { 
    10121007                $objQuery->commit(); 
    10131008            } 
     
    10171012        //差分対象カテゴリIDの重複を除去 
    10181013        $arrDiffCategory_id = array_unique($arrDiffCategory_id); 
     1014         
     1015        //dtb_category_countの更新 差分のあったカテゴリだけ更新する。 
     1016        foreach($arrDiffCategory_id as $cid) { 
     1017            $sqlval = array(); 
     1018            $sqlval['create_date'] = 'Now()'; 
     1019            $sqlval['product_count'] = (string)$arrNew[$cid]; 
     1020            if($sqlval['product_count'] =="") { 
     1021                $sqlval['product_count'] = (string)'0'; 
     1022            } 
     1023            if(isset($arrOld[$cid])) { 
     1024                $objQuery->update('dtb_category_count', $sqlval, 'category_id = ?', array($cid)); 
     1025            }else{ 
     1026                $sqlval['category_id'] = $cid; 
     1027                $objQuery->insert('dtb_category_count', $sqlval); 
     1028            } 
     1029        } 
     1030         
    10191031        //差分があったIDとその親カテゴリIDのリストを取得する 
    10201032        $arrTgtCategory_id = array(); 
     
    10301042        $arrTgtCategory_id = array_unique($arrTgtCategory_id); 
    10311043 
    1032         //dtb_cateogry_total_count 集計処理開始 
    1033         //旧データの削除 
    1034         $objQuery->query("DELETE FROM dtb_category_total_count WHERE category_id in (" . implode(',',$arrTgtCategory_id) . ")"); 
    1035  
    1036         //カテゴリ毎に処理 
     1044        //dtb_category_total_count 集計処理開始 
     1045        //更新対象カテゴリIDだけ集計しなおす。 
     1046        $arrUpdateData = array(); 
    10371047        foreach ($arrTgtCategory_id as $category_id) { 
    10381048            $arrval = array(); 
     
    10481058 
    10491059            $from = $objProduct->alldtlSQL($sql_where_product_ids); 
    1050             $sql = <<< __EOS__ 
    1051                 INSERT INTO dtb_category_total_count (category_id, product_count, create_date) 
    1052                 SELECT 
    1053                     ? 
    1054                     ,count(*) 
    1055                     ,now() 
    1056                 FROM $from 
    1057                WHERE $where 
    1058 __EOS__; 
    1059             $objQuery->query($sql, $arrval); 
    1060         } 
    1061         //トランザクションの終了処理。 
    1062         if($is_out_tarns){ 
     1060            $sql = "SELECT count(*) FROM $from WHERE $where "; 
     1061            $arrUpdateData[ $category_id ] = $objQuery->getOne($sql, $arrval); 
     1062        } 
     1063        // 更新対象だけを更新。 
     1064        foreach($arrUpdateData as $cid => $count) { 
     1065            $sqlval = array(); 
     1066            $sqlval['create_date'] = 'Now()'; 
     1067            $sqlval['product_count'] = $count; 
     1068            if($sqlval['product_count'] =="") { 
     1069                $sqlval['product_count'] = (string)'0'; 
     1070            } 
     1071            $ret = $objQuery->update('dtb_category_total_count', $sqlval, 'category_id = ?', array($cid)); 
     1072            if(!$ret) { 
     1073                $sqlval['category_id'] = $cid; 
     1074                $ret = $objQuery->insert('dtb_category_total_count', $sqlval); 
     1075            } 
     1076        } 
     1077        // トランザクション音終了処理 
     1078        if($is_out_trans) { 
    10631079            $objQuery->commit(); 
    10641080        } 
Note: See TracChangeset for help on using the changeset viewer.