no-image

MySQLの重いサブクエリを解決する方法

EC-CUBE内の話なんだけどもSQLを完全に書き直してしまっているので一般的なMySQLの話です。

参考サイトはこちらです
漢(オトコ)のコンピュータ道: Using filesort

商品検索をする場合に必要なtableが3つあり、すべてjoinした状態で検索をするSQLを書いてます。

大体こんな感じのクエリ
~~~
SELECT
count(*)
FROM

(
SELECT
P.*,
Ps.rank,
MIN(Pc.price02) AS price02_min
FROM
dtb_products_a AS A,
dtb_products_b AS B,
dtb_products_c AS C
WHERE
A.product_id = B.product_id
AND
A.product_id = C.product_id
AND
B.id = 1
AND
A.flag = 0
AND
A.id IS NOT NULL
AND
del_flg = 0
AND
status = 1
GROUP BY
A.product_id
) AS List
WHERE
category_id IN ()
ORDER BY
rank DESC
LIMIT 1

~~~

ところが商品数が増えてくると『Using temporary; Using filesort』の重い処理がのしかかってきました。。

この時点で15000商品の登録で画面表示に8秒ほど、3秒ルールも越えてるしどうするかーと検索した結果

~~~
SELECT
count(*)
FROM

(
SELECT
P.*,
Ps.rank,
MIN(Pc.price02) AS price02_min
FROM
dtb_products_a AS A,
dtb_products_b AS B,
dtb_products_c AS C
WHERE
A.product_id = B.product_id
AND
A.product_id = C.product_id
AND
B.id = 1
AND
A.flag = 0
AND
A.id IS NOT NULL
AND
del_flg = 0
AND
status = 1
GROUP BY
A.product_id
LIMIT 15000
) AS List
WHERE
category_id IN ()
ORDER BY
rank DESC
LIMIT 1

~~~

LIMIT 15000 の1行を加えただけです(商品数をとってきて突っ込んだ)

これだけで表示は3秒に!これ以上の量でもいけるのかは要調査ですが1行足しただけで劇的に変わったので記録ですっ

と、いうわけでサブクエリ内が重いなーと感じたらまずはlimitを入れてみることをオススメします