

次のようなSQL文があります。  
こちらのSQLでは、INNER JOINしているテーブル及び、WHERE文で対象としているテーブルは、２つしかありません。  
これでしたら10秒ほどで、集計が完了します。

しかし、今回の要件上、INNER JOINするテーブル数は、12個あり、  
同様にINNER JOINとWHERE文を追加していき実行すると、1時間以上かかってしまいます。

[code]

    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;
    
[/code]

SQLの速度改善をしたいのですが、これ以上絞り込む条件がないため、  
SQL文の見直しにより、改善できる方法を探しております。

尚、バッチ処理にするという案は今回の要件上NGでした。

生のSQL文で記述しておりますが、実際はRuby on Railsのアプリケーション上で実行します。  
その為、非同期処理というのも模索しておりますが、今回、集計した結果をDBにINSERTするため、  
非同期処理にすると、本来データが入ってほしいレコードにデータが入らないという恐れを懸念しております。

INNER JOIN を LEFT OUTER JOIN にしたり等、不勉強ながら試行錯誤しておりますが、なかなか改善につながりません。

理想は1~2分で完了してほしいです。

また、この集計処理は、期間を変えて実行することはあっても、同じSQL文を何度も使うということはないので、  
クエリキャッシュをするというのもあまり意味がないと思っております。

また、外部キー周りにindexキーはつけております。

宜しくお願い致します。


CC BY-SA 3.0
2017-07-29T11:39:52.333
36771
2018-02-16T14:37:29.777
13175
question
mysql sql
12テーブルをINNER JOINしているSQL文(コードあり)の速度改善をしたいです。LEFT OUTER JOINに変えたりしておりますが、改善につながりません。


ご希望の回答ではありませんが、実行するSQL文に対し`EXPLAIN`すると「実行計画」が出力されるので、どこの記述(検索条件、結合、etc.)に時間がかかっているかわかると思います。

＃Oracleの場合「`EXPLAIN PLAN`」、PostgreSQLの場合「`EXPLAIN
ANALYE`」、MySQLだと「`EXPLAIN`」と微妙に文法が異なりますが、「実行計画」が取得できる点は一緒です。

例: PostgreSQLの場合:

[code]

    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;
    
[/code]

`EXPLAIN`の結果を見て「遅い」箇所を突き止めるのがよいかと思います。


CC BY-SA 3.0
2017-07-29T12:04:04.193
36772
2017-07-29T12:04:04.193
20098
36771
answer