Eloquentで発行されるSQLがサブクエリ全開だった

セルプロモート株式会社で、新規自社プロダクト開発を担当してますsasamonと申します。

先日こんなことが発生しました。

LaravelのEloquentで発行しているSQLが突然遅くなった。今まで数秒で終わってた処理が1分ぐらいかかってる。

あれ、何だこれと思いdd()メソッドでSQLを確認、EXPLAIN取得したらこんな感じでした

+------+--------------------+----------------------+--------+-----------------------------------------------------------------------------------------+-----------------------------------------------+---------+-------------------------------------------+-------+-------------+
| id   | select_type        | table                | type   | possible_keys                                                                           | key                                           | key_len | ref                                       | rows  | Extra       |
+------+--------------------+----------------------+--------+-----------------------------------------------------------------------------------------+-----------------------------------------------+---------+-------------------------------------------+-------+-------------+
|    1 | PRIMARY            | xxxxxxxx           | ALL    | NULL                                                                                    | NULL                                          | NULL    | NULL                                      | 20859 | Using where |
|    5 | DEPENDENT SUBQUERY | xxxxxxxx   | ref    | xxxxxxxx          | xxxxxxxx       | 9       | func                                      | 1     | Using where |
|    5 | DEPENDENT SUBQUERY | xxxxxxxx            | eq_ref | PRIMARY                                                                                 | PRIMARY                                       | 8       | xxxxxxxx | 1     | Using where |
|    4 | MATERIALIZED       | xxxxxxxx            | ALL    | PRIMARY                                                                                 | NULL                                          | NULL    | NULL                                      | 19    | Using where |
|    4 | MATERIALIZED       | xxxxxxxx      | ref    | xxxxxxxx                | xxxxxxxx           | 8       | xxxxxxxx                   | 182   |             |
|    3 | MATERIALIZED       | xxxxxxxx       | ALL    | PRIMARY                                                                                 | NULL                                          | NULL    | NULL                                      | 23    | Using where |
|    3 | MATERIALIZED       | xxxxxxxx | ref    | xxxxxxxx | xxxxxxxx | 8       | xxxxxxxx              | 155   |             |
|    2 | DEPENDENT SUBQUERY | xxxxxxxx        | ALL    | PRIMARY                                                                                 | NULL                                          | NULL    | NULL                                      | 30    | Using where |
|    2 | DEPENDENT SUBQUERY | xxxxxxxx  | ref    | xxxxxxxx    | xxxxxxxx   | 8       | xxxxxxxx               | 706   | Using where |
+------+--------------------+----------------------+--------+-----------------------------------------------------------------------------------------+-----------------------------------------------+---------+-------------------------------------------+-------+-------------+

DEPENDENT SUBQUERYでちゃってるー。。。

以下でも紹介されてますが、DEPENDENT SUBQUERYはかなり遅い。

nippondanji.blogspot.com

クエリ組み立ててる部分を見直して最終的には以下な感じに。

+------+--------------+----------------------+------+-----------------------------------------------------------------------------------------+-----------------------------------------------+---------+------------------------------+-------+-------------+
| id   | select_type  | table                | type | possible_keys                                                                           | key                                           | key_len | ref                          | rows  | Extra       |
+------+--------------+----------------------+------+-----------------------------------------------------------------------------------------+-----------------------------------------------+---------+------------------------------+-------+-------------+
|    1 | PRIMARY      | xxxxxxxx           | ALL  | NULL                                                                                    | NULL                                          | NULL    | NULL                         | 20923 | Using where |
|    5 | MATERIALIZED | xxxxxxxx            | ALL  | PRIMARY                                                                                 | NULL                                          | NULL    | NULL                         | 65    | Using where |
|    5 | MATERIALIZED | xxxxxxxx   | ref  | xxxxxxxx          | xxxxxxxx        | 9       | xxxxxxxx      | 125   |             |
|    4 | MATERIALIZED | xxxxxxxx            | ALL  | PRIMARY                                                                                 | NULL                                          | NULL    | NULL                         | 19    | Using where |
|    4 | MATERIALIZED | xxxxxxxx      | ref  | xxxxxxxx                | xxxxxxxx           | 8       | xxxxxxxx      | 182   |             |
|    3 | MATERIALIZED | xxxxxxxx       | ALL  | PRIMARY                                                                                 | NULL                                          | NULL    | NULL                         | 23    | Using where |
|    3 | MATERIALIZED | xxxxxxxx | ref  | xxxxxxxx | xxxxxxxx | 8       | xxxxxxxx | 155   |             |
|    2 | MATERIALIZED | xxxxxxxx        | ALL  | PRIMARY                                                                                 | NULL                                          | NULL    | NULL                         | 30    | Using where |
|    2 | MATERIALIZED | xxxxxxxx  | ref  | xxxxxxxx    | xxxxxxxx   | 8       | xxxxxxxx  | 706   |             |
+------+--------------+----------------------+------+-----------------------------------------------------------------------------------------+-----------------------------------------------+---------+------------------------------+-------+-------------+

ORMって使いこなすと便利だけど、複雑な条件組み立てるとなかなか難しいなぁと思う今日このごろ。

ってこの記事を書きながら色々調べてたらEXPLAINもEloquentでとれるのね。。。知らなかった。。。

www.amitmerchant.com

世の中知らないことだらけです。

セルプロモート株式会社では以下からエンジニアを募集してます、興味がある方はぜひご覧いただければと!

cellpromote.biz