Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

商品一覧, 商品詳細のパフォーマンス改善 #296

Merged
merged 1 commit into from
Sep 17, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 17 additions & 8 deletions data/class/SC_Product.php
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,10 @@ public function findProductCount(&$objQuery, $arrVal = array())
* の配列を取得する.
*
* @param SC_Query $objQuery SC_Query インスタンス
* @param array $product_ids 商品IDの配列
* @return array 商品一覧の配列
*/
public function lists(&$objQuery)
public function lists(&$objQuery, $product_ids = array())
{
$col = <<< __EOS__
product_id
Expand All @@ -144,7 +145,7 @@ public function lists(&$objQuery)
,del_flg
,update_date
__EOS__;
$res = $objQuery->select($col, $this->alldtlSQL());
$res = $objQuery->select($col, $this->alldtlSQL('', $product_ids));

return $res;
}
Expand All @@ -169,8 +170,13 @@ public function getListByProductIds(&$objQuery, $arrProductId = array())
$where = 'alldtl.product_id IN (' . SC_Utils_Ex::repeatStrWithSeparator('?', count($arrProductId)) . ')';
$where .= ' AND alldtl.del_flg = 0';

$objQuery->setWhere($where, $arrProductId);
$arrProducts = $this->lists($objQuery);
$objQuery->setWhere(
$where,
// SC_DB_DBFactory::alldtlSQL() で生成される追加条件のため
// product_id の配列を生成ておく
array_merge($arrProductId, $arrProductId, $arrProductId)
);
$arrProducts = $this->lists($objQuery, $arrProductId);

// 配列のキーを商品IDに
$arrProducts = SC_Utils_Ex::makeArrayIDToKey('product_id', $arrProducts);
Expand Down Expand Up @@ -201,9 +207,11 @@ public function getDetail($product_id)
{
$objQuery = SC_Query_Ex::getSingletonInstance();

$from = $this->alldtlSQL();
$from = $this->alldtlSQL('', array($product_id));
$where = 'product_id = ?';
$arrWhereVal = array($product_id);
// SC_DB_DBFactory::alldtlSQL() で生成される追加条件のため
// product_id の配列を生成ておく
$arrWhereVal = array($product_id, $product_id, $product_id);
$arrProduct = (array)$objQuery->getRow('*', $from, $where, $arrWhereVal);

// 税込金額を設定する
Expand Down Expand Up @@ -621,13 +629,14 @@ public static function setIncTaxToProduct(&$arrProduct)
* 商品詳細の SQL を取得する.
*
* @param string $where_products_class 商品規格情報の WHERE 句
* @param array $product_ids 商品IDの配列
* @return string 商品詳細の SQL
*/
public function alldtlSQL($where_products_class = '')
public function alldtlSQL($where_products_class = '', $product_ids = array())
{
$objDBFactory = SC_DB_DBFactory_Ex::getInstance();

return $objDBFactory->alldtlSQL($where_products_class);
return $objDBFactory->alldtlSQL($where_products_class, $product_ids);
}

/**
Expand Down
18 changes: 15 additions & 3 deletions data/class/db/SC_DB_DBFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -241,13 +241,25 @@ function addLimitOffset($sql, $limit = 0, $offset = 0)
* 商品詳細の SQL を取得する.
*
* @param string $where_products_class 商品規格情報の WHERE 句
* @param array $product_ids 商品IDの配列
* @return string 商品詳細の SQL
*/
public function alldtlSQL($where_products_class = '')
public function alldtlSQL($where_products_class = '', $product_ids = array())
{
if (!SC_Utils_Ex::isBlank($where_products_class)) {
$where_products_class = 'AND (' . $where_products_class . ')';
}

$dtb_products_table = 'dtb_products';
$product_id_cause = '';

// dtb_products_class の Full scan を防ぐため,
// 商品IDが特定できている場合は, 先に product_id で対象を絞り込む
if (count($product_ids) > 0) {
$in = SC_Utils_Ex::repeatStrWithSeparator('?', count($product_ids));
$product_id_cause = ' AND product_id IN ('.$in.')';
$dtb_products_table = ' ( SELECT * FROM dtb_products WHERE product_id IN ('.$in.') ) AS dtb_products';
}
/*
* point_rate, deliv_fee は商品規格(dtb_products_class)ごとに保持しているが,
* 商品(dtb_products)ごとの設定なので MAX のみを取得する.
Expand All @@ -269,7 +281,7 @@ public function alldtlSQL($where_products_class = '')
,T4.point_rate
,T4.deliv_fee
,dtb_maker.name AS maker_name
FROM dtb_products
FROM $dtb_products_table
INNER JOIN (
SELECT product_id
,MIN(product_code) AS product_code_min
Expand All @@ -285,7 +297,7 @@ public function alldtlSQL($where_products_class = '')
,MAX(point_rate) AS point_rate
,MAX(deliv_fee) AS deliv_fee
FROM dtb_products_class
WHERE del_flg = 0 $where_products_class
WHERE del_flg = 0 $where_products_class $product_id_cause
GROUP BY product_id
) AS T4
ON dtb_products.product_id = T4.product_id
Expand Down
44 changes: 0 additions & 44 deletions data/class/db/dbfactory/SC_DB_DBFactory_PGSQL.php
Original file line number Diff line number Diff line change
Expand Up @@ -282,48 +282,4 @@ public function listTables(SC_Query &$objQuery)

return $objQuery->getCol($col, $from, $where);
}

/**
* 商品詳細の SQL を取得する.
*
* PostgreSQL 用にチューニング。
* @param string $where_products_class 商品規格情報の WHERE 句
* @return string 商品詳細の SQL
*/
public function alldtlSQL($where_products_class = '')
{
if (!SC_Utils_Ex::isBlank($where_products_class)) {
$where_products_class = 'AND (' . $where_products_class . ')';
}
/*
* point_rate, deliv_fee は商品規格(dtb_products_class)ごとに保持しているが,
* 商品(dtb_products)ごとの設定なので MAX のみを取得する.
*/
$sub_base = "FROM dtb_products_class WHERE del_flg = 0 AND product_id = dtb_products.product_id $where_products_class";
$sql = <<< __EOS__
(
SELECT
dtb_products.*
,dtb_maker.name AS maker_name
,(SELECT MIN(product_code) $sub_base) AS product_code_min
,(SELECT MAX(product_code) $sub_base) AS product_code_max
,(SELECT MIN(price01) $sub_base) AS price01_min
,(SELECT MAX(price01) $sub_base) AS price01_max
,(SELECT MIN(price02) $sub_base) AS price02_min
,(SELECT MAX(price02) $sub_base) AS price02_max
,(SELECT MIN(stock) $sub_base) AS stock_min
,(SELECT MAX(stock) $sub_base) AS stock_max
,(SELECT MIN(stock_unlimited) $sub_base) AS stock_unlimited_min
,(SELECT MAX(stock_unlimited) $sub_base) AS stock_unlimited_max
,(SELECT MAX(point_rate) $sub_base) AS point_rate
,(SELECT MAX(deliv_fee) $sub_base) AS deliv_fee
FROM dtb_products
LEFT JOIN dtb_maker
ON dtb_products.maker_id = dtb_maker.maker_id
WHERE EXISTS(SELECT * $sub_base)
) AS alldtl
__EOS__;

return $sql;
}
}