質問: `goods`.`artist_id`\ WHERE (`events`.`created_at` BETWEEN '2017-01-01' AND '2017-07-30')\ AND (`goods`.`created_at` BETWEEN '2017-01-01' AND '2017-07-30')\ GROUP BY artists.user_id, artists.staff_id; ``` SQLの速度改善をしたいのですが、これ以上絞り込む条件がないため、 SQL文の見直しにより、改善できる方法を探しております。 尚、バッチ処理にするという案は今回の要件上NGでした。 生のSQL文で記述しておりますが、実際はRuby on Railsのアプリケーション上で実行します。 その為、非同期処理というのも模索しておりますが、今回、集計した結果をDBにINSERTするため、 非同期処理にすると、本来データが入ってほしいレコードにデータが入らないという恐れを懸念しております。 INNER JOIN を LEFT OUTER JOIN にしたり等、不勉強ながら試行錯誤しておりますが、なかなか改善につながりません。 理想は1~2分で完了してほしいです。 また、この集計処理は、期間を変えて実行することはあっても、同じSQL文を何度も使うということはないので、 クエリキャッシュをするというのもあまり意味がないと思っております。 また、外部キー周りにindexキーはつけております。 宜しくお願い致します。
回答: ご希望の回答ではありませんが、実行するSQL文に対し`EXPLAIN`すると「実行計画」が出力されるので、どこの記述(検索条件、結合、etc.)に時間がかかっているかわかると思います。 #Oracleの場合「`EXPLAIN PLAN`」、PostgreSQLの場合「`EXPLAIN ANALYE`」、MySQLだと「`EXPLAIN`」と微妙に文法が異なりますが、「実行計画」が取得できる点は一緒です。 例: PostgreSQLの場合: ``` EXPLAIN ANALYZE SELECT artists.user_id, artists.staff_id, Sum(events.sum),\ Sum(goods.sum),\ FROM artists\ INNER JOIN `events` ON `artists`.`id` = `events`.`artist_id`\ INNER JOIN `goods` ON `artists`.`id` = `goods`.`artist_id`\ WHERE (`events`.`created_at` BETWEEN '2017-01-01' AND '2017-07-30')\ AND (`goods`.`created_at` BETWEEN '2017-01-01' AND '2017-07-30')\ GROUP BY artists.user_id, artists.staff_id; ``` `EXPLAIN`の結果を見て「遅い」箇所を突き止めるのがよいかと思います。