EC-CUBE MYSQLでの速度改善01
date_range
- ENGINEER
今週から、全4回に分けてEC-CUBEのMYSQLにおける速度改善について書いていきます。
EC-CUBEでの速度改善は主にMYSQLのクエリ部分の改善で対応できます。
例えば 商品データを取得する場合
SELECT
*
FROM
dtb_products LEFT JOIN
dtb_products_class ON (dtb_products.product_id = dtb_products_class.product_id)
WHERE
dtb_products.del_flg = 0 AND
dtb_products.status = 1 AND
dtb_products_class.del_flg = 0
ORDER BY product_id DESC
LIMIT 10
というクエリがあった場合、このままでいいように見えますが 実際には
SELECT
*
FROM
(
SELECT
*
FROM
dtb_products
WHERE
dtb_products.del_flg = 0 AND
dtb_products.status = 1
ORDER BY product_id DESC
LIMIT 10
) p INNER JOIN
dtb_products_class ON (p.product_id = dtb_products_class.product_id)
WHERE
dtb_products_class.del_flg = 0
ORDER BY p.product_id
のように書いた方が早くなります。
商品データが多ければ多いほど劇的に。
EC-CUBEのデフォルトで効果がある場所は
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 のみを取得する.
*/
$sql = <<< __EOS__
(
SELECT
dtb_products.*
,T4.product_code_min
,T4.product_code_max
,T4.price01_min
,T4.price01_max
,T4.price02_min
,T4.price02_max
,T4.stock_min
,T4.stock_max
,T4.stock_unlimited_min
,T4.stock_unlimited_max
,T4.point_rate
,T4.deliv_fee
,dtb_maker.name AS maker_name
FROM dtb_products
INNER JOIN (
SELECT product_id
,MIN(product_code) AS product_code_min
,MAX(product_code) AS product_code_max
,MIN(price01) AS price01_min
,MAX(price01) AS price01_max
,MIN(price02) AS price02_min
,MAX(price02) AS price02_max
,MIN(stock) AS stock_min
,MAX(stock) AS stock_max
,MIN(stock_unlimited) AS stock_unlimited_min
,MAX(stock_unlimited) AS stock_unlimited_max
,MAX(point_rate) AS point_rate
,MAX(deliv_fee) AS deliv_fee
FROM dtb_products_class
WHERE del_flg = 0 $where_products_class
GROUP BY product_id
) AS T4
ON dtb_products.product_id = T4.product_id
LEFT JOIN dtb_maker
ON dtb_products.maker_id = dtb_maker.maker_id
) AS alldtl
__EOS__;
return $sql;
}
この部分で、オススメ商品とか一覧で使われている、商品IDの配列を渡して商品のデータを取得する部分で、メソッドに対して配列をこのalldtlSQLのメソッドに対して引き渡し、INNER JOINされている dtb_products_classに対して絞り込むクエリを追加することで効果が現れます。
MYSQLの場合はJOINのコストが結構高くなる場合があり、EC-CUBEにおいては顕著にその影響が出てきます。
細かい所ですが、後々サイトが重たくなるとかを防ぐ為に先に色々負荷対策を行っておいた方が安心です。
速度改善の依頼はこちらから。