ブログ B L O G

EC-CUBE MYSQLでの速度改善02

# MYSQLでの速度改善02 ## SQL_CALC_FOUND_ROWSで高速化。 EC-CUBEの一覧では ```sql SELECT COUNT(*) FROM ?? WHERE ??? = ??? AND ..... のような形で全体の件数を取得した後、LIMITとOFFSETを確定させてデータを取得するようになっています。 MYSQLの場合、WHEREで絞り込んだ結果でCOUNT(*)を行うと速度がかなり遅いということがあります。
SELECT
	COUNT(*)
FROM
	dtb_products 
WHERE
	del_flg = 0 AND
	status = 1 AND
	EXISTS(
		SELECT
			*
		FROM
			dtb_product_categories
		WHERE
			category_id IN (1,2,3,4,5)
	)
で、全体の件数を取得してから、
SELECT
	*
FROM
	dtb_products 
WHERE
	del_flg = 0 AND
	status = 1 AND
	EXISTS(
		SELECT
			*
		FROM
			dtb_product_categories
		WHERE
			category_id IN (1,2,3,4,5)
	)
LIMIT 20 OFFSET 20
```

取得したいデータを取るクエリを発行しています。
おそらくPostgresqlと合わせる為にこのような形になっていると思うんですが、
MYSQLのみに限定すればSQL_CALC_FOUND_ROWSという便利な関数があります。

それを使う事で多少なりとも速度を速くする事ができます。

使い方は

```sql
SELECT
	SQL_CALC_FOUND_ROWS
	*
FROM
	dtb_products 
WHERE
	del_flg = 0 AND
	status = 1 AND
	EXISTS(
		SELECT
			*
		FROM
			dtb_product_categories
		WHERE
			category_id IN (1,2,3,4,5)
	)
LIMIT 20 OFFSET 20
```

こんな形で先に取得したいデータを取っておいて、
その後に

```sql
SELECT FOUND_ROWS();
```

を実行で全件取得できます。

これを行うことで重たい処理が1回で済むことになるので、
負荷的にはほぼ半分くらいになります。

件数によって何がいいかは変わりますが、ECくらいの件数だとSQL_CALC_FOUND_ROWSを使用する方が早いと思います。
ちなみにPostgresqlはこの関数は使用できません。

ECサイトを運営する場合、

商品一覧やレビュー一覧、マイページの購入履歴一覧等で使用すると効果的です。

実際はカスタマイズによって検索する項目等も変更の場合がありますが、
負荷の高いと思われるクエリに関してはきっちりINDEXを有効的に張って
速度の事も考えたうえで実装するのがいいかと思います。

速度改善の依頼は[こちら](https://www.sunday.systems/contact)から。
                    

お問合せ

サンデイシステムズへのお問合わせは、下記よりコンタクトフォームをご利用下さい。
担当の者より、追ってご連絡させていただきます。