Changeset 21544


Ignore:
Timestamp:
2012/02/22 01:27:53 (9 years ago)
Author:
Seasoft
Message:

#1656 (カテゴリ登録のロジックを高速化)
#1661 (共通ロジックを利用する)

  • SC_Query#getCol

#1660 (SC_Helper_DB#sfCountCategory メモリ消費が激しい)
#1659 (SC_Helper_DB#sfCountCategory メモリリークが発生する)

Location:
branches/version-2_12-dev/data/class
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • branches/version-2_12-dev/data/class/SC_Query.php

    r21514 r21544  
    3838    var $groupby = ''; 
    3939    var $order = ''; 
    40     var $force_run; 
     40    var $force_run = false; 
    4141 
    4242    /** 
     
    469469     * @param array $arrSql array('カラム名' => 'SQL文', ...)の連想配列 
    470470     * @param array $arrSqlVal SQL文の中で使用するプレースホルダ配列 
    471      * @return 
    472      */ 
    473     function insert($table, $sqlval, $arrSql = array(), $arrSqlVal = array()) { 
     471     * @param string $from FROM 句・WHERE 句 
     472     * @param string $arrFromVal FROM 句・WHERE 句で使用するプレースホルダ配列 
     473     * @return integer|DB_Error 挿入件数またはDB_Error 
     474     */ 
     475    function insert($table, $sqlval, $arrSql = array(), $arrSqlVal = array(), $from = '', $arrFromVal = array()) { 
    474476        $strcol = ''; 
    475477        $strval = ''; 
     
    502504        } 
    503505        // 文末の','を削除 
    504         $strcol = preg_replace("/,$/", "", $strcol); 
    505         $strval = preg_replace("/,$/", "", $strval); 
    506         $sqlin = "INSERT INTO $table(" . $strcol. ") VALUES (" . $strval . ")"; 
     506        $strcol = rtrim($strcol, ','); 
     507        $strval = rtrim($strval, ','); 
     508        $sqlin = "INSERT INTO $table($strcol) SELECT $strval"; 
     509 
     510        if (strlen($from) >= 1) { 
     511            $sqlin .= ' ' . $from; 
     512            $arrVal = array_merge($arrVal, $arrFromVal); 
     513        } 
     514 
    507515        // INSERT文の実行 
    508516        $ret = $this->query($sqlin, $arrVal, false, null, MDB2_PREPARE_MANIP); 
  • branches/version-2_12-dev/data/class/db/dbfactory/SC_DB_DBFactory_MYSQL.php

    r21527 r21544  
    304304        return $definition; 
    305305    } 
     306 
     307    /** 
     308     * 擬似表を表すSQL文(FROM 句)を取得する 
     309     * 
     310     * @return string 
     311     */ 
     312    function getDummyFromClauseSql() { 
     313        return 'FROM DUAL'; 
     314    } 
    306315} 
  • branches/version-2_12-dev/data/class/db/dbfactory/SC_DB_DBFactory_PGSQL.php

    r21527 r21544  
    239239        return array(); 
    240240    } 
     241 
     242    /** 
     243     * 擬似表を表すSQL文(FROM 句)を取得する 
     244     * 
     245     * @return string 
     246     */ 
     247    function getDummyFromClauseSql() { 
     248        return ''; 
     249    } 
    241250} 
  • branches/version-2_12-dev/data/class/helper/SC_Helper_DB.php

    r21527 r21544  
    540540     */ 
    541541    function addProductBeforCategories($category_id, $product_id) { 
     542        $objQuery =& SC_Query_Ex::getSingletonInstance(); 
    542543 
    543544        $sqlval = array('category_id' => $category_id, 
    544545                        'product_id' => $product_id); 
    545546 
    546         $objQuery =& SC_Query_Ex::getSingletonInstance(); 
    547  
    548         // 現在の商品カテゴリを取得 
    549         $arrCat = $objQuery->select('product_id, category_id, rank', 
    550                                     'dtb_product_categories', 
    551                                     'category_id = ?', 
    552                                     array($category_id)); 
    553  
    554         $max = '0'; 
    555         foreach ($arrCat as $val) { 
    556             // 同一商品が存在する場合は登録しない 
    557             if ($val['product_id'] == $product_id) { 
    558                 return; 
    559             } 
    560             // 最上位ランクを取得 
    561             $max = ($max < $val['rank']) ? $val['rank'] : $max; 
    562         } 
    563         $sqlval['rank'] = $max + 1; 
    564         $objQuery->insert('dtb_product_categories', $sqlval); 
     547        $arrSql = array(); 
     548        $arrSql['rank'] = '(SELECT COALESCE(MAX(rank), 0) FROM dtb_product_categories sub WHERE category_id = ?) + 1'; 
     549 
     550        $from_and_where = $objQuery->dbFactory->getDummyFromClauseSql(); 
     551        $from_and_where .= ' WHERE NOT EXISTS(SELECT * FROM dtb_product_categories WHERE category_id = ? AND product_id = ?)'; 
     552        $objQuery->insert('dtb_product_categories', $sqlval, $arrSql, array($category_id), $from_and_where, array($category_id, $product_id)); 
    565553    } 
    566554 
     
    711699        } 
    712700 
     701        unset($arrCategoryCountOld); 
     702        unset($arrCategoryCountNew); 
     703 
    713704        $arrDiffCategory_id = array(); 
    714705        //新しいカテゴリ一覧から見て商品数が異なるデータが無いか確認 
     
    758749        } 
    759750 
     751        unset($arrOld); 
     752        unset($arrNew); 
     753 
    760754        //差分があったIDとその親カテゴリIDのリストを取得する 
    761755        $arrTgtCategory_id = array(); 
     
    763757            $arrTgtCategory_id[] = $parent_category_id; 
    764758            $arrParentID = $this->sfGetParents('dtb_category', 'parent_category_id', 'category_id', $parent_category_id); 
    765             $arrTgtCategory_id = array_merge($arrTgtCategory_id, $arrParentID); 
    766         } 
    767  
    768         //重複を取り除く 
    769         $arrTgtCategory_id = array_unique($arrTgtCategory_id); 
     759            $arrTgtCategory_id = array_unique(array_merge($arrTgtCategory_id, $arrParentID)); 
     760        } 
     761 
     762        unset($arrDiffCategory_id); 
    770763 
    771764        //dtb_category_total_count 集計処理開始 
    772765        //更新対象カテゴリIDだけ集計しなおす。 
    773766        $arrUpdateData = array(); 
     767        $where_products_class = ''; 
     768        if (NOSTOCK_HIDDEN) { 
     769            $where_products_class .= '(stock >= 1 OR stock_unlimited = 1)'; 
     770        } 
     771        $from = $objProduct->alldtlSQL($where_products_class); 
    774772        foreach ($arrTgtCategory_id as $category_id) { 
    775773            $arrval = array(); 
     
    777775            if ($tmp_where != '') { 
    778776                $sql_where_product_ids = 'product_id IN (SELECT product_id FROM dtb_product_categories WHERE ' . $tmp_where . ')'; 
    779                 $arrval = array_merge((array)$tmp_arrval, (array)$tmp_arrval); 
     777                $arrval = $tmp_arrval; 
    780778            } else { 
    781779                $sql_where_product_ids = '0<>0'; // 一致させない 
     
    783781            $where = "($sql_where) AND ($sql_where_product_ids)"; 
    784782 
    785             $where_products_class = ''; 
    786             if (NOSTOCK_HIDDEN) { 
    787                 $where_products_class .= '(stock >= 1 OR stock_unlimited = 1)'; 
    788             } 
    789  
    790             $from = $objProduct->alldtlSQL($where_products_class); 
    791             $sql = "SELECT count(*) FROM $from WHERE $where "; 
    792             $arrUpdateData[ $category_id ] = $objQuery->getOne($sql, $arrval); 
    793         } 
     783            $arrUpdateData[$category_id] = $objQuery->count($from, $where, $arrval); 
     784        } 
     785 
     786        unset($arrTgtCategory_id); 
     787 
    794788        // 更新対象だけを更新。 
    795789        foreach ($arrUpdateData as $cid => $count) { 
     
    861855        $where = "$pid_name IN (" . implode(',', array_fill(0, count($arrPID), '?')) . ")"; 
    862856 
    863         $ret = $objQuery->select($id_name, $table, $where, $arrPID); 
    864  
    865         $arrChildren = array(); 
    866         foreach ($ret as $val) { 
    867             $arrChildren[] = $val[$id_name]; 
    868         } 
    869  
    870         return $arrChildren; 
     857        $return = $objQuery->getCol($id_name, $table, $where, $arrPID); 
     858 
     859        return $return; 
    871860    } 
    872861 
Note: See TracChangeset for help on using the changeset viewer.