【SQL】GROUP BYが遅いときのチューニング方法


ここではORACLEデータベースのSQLで、GROUPBYを使って遅いときのチューニング方法を紹介します。

SQLの実行計画の見方や確認方法については↓で紹介していますので参考にしてください。
>>【ORACLE】SQLの実行計画の見方
>>【ORACLE】SQLの実行計画を取得する方法

GROUP BYが遅いときのチューニング方法

GROUPBYが遅いSQLでよくあるのが、集約する項目が無駄に多い場合です。

例えば、売上データを顧客ごと、担当者ごと、部署ごとに集約して集計する場合です。

集約する項目として必要なものは、顧客CDと担当者CD、部署CDですが、各項目の名称や集約に全く関係のない項目もGROUPBYの項目にしています。

GROUPBYは列挙した列、つまり集約する項目が多いと処理は遅くなります。

もちろん、集約項目の数だけではありませんが、まずは無駄な集約項目を無くすことから改修を始めることをおすすめします。

GROUPBYをチューニングするSQLサンプル

GROUPBYをチューニングするSQLのサンプルを紹介します。

・チューニング前
 次のSQLでは顧客名や担当者名、部署名といった名称の項目もGROUPBYに列挙しています。

select
    a.顧客コード
    ,b.顧客名
    ,a.担当者コード
    ,c.担当者名
    ,a.部署コード
    ,d.部署名
    ,SUM(売上金額)
from売上 a
    ,顧客マスタ b
    ,担当者マスタ c
    ,部門マスタ d
where
    a.顧客コード = b.顧客コード
    and a.担当者コード = c.担当者コード
    and a.部署コード = d.部署コード
group by
    a.顧客コード
    ,b.顧客名
    ,a.担当者コード
    ,c.担当者名
    ,a.部署コード
    ,d.部署名
;

・チューニング後
 次のSQLでは、集計に不要な項目をGROUPBYから外しました。名称が必要な場合は、GROUPBYした後にマスタを外部結合するなどして取得することも出来ます。

select
    x.顧客コード
    ,b.顧客名
    ,x.担当者コード
    ,c.担当者名
    ,x.部署コード
    ,d.部署名
    ,x.売上金額
from
    (select
        a.顧客コード
        ,a.担当者コード
        ,a.部署コード
        ,SUM(売上金額) as 売上金額
    from
        売上 a
    group by
        a.顧客コード
        ,a.担当者コード
        ,a.部署コード) x
    ,顧客マスタ b
    ,担当者マスタ c
    ,部門マスタ d
where
    x.顧客コード = b.顧客コード
    and x.担当者コード = c.担当者コード
    and x.部署コード = d.部署コード
;

まとめ

GROUPBYを使ったSQLが遅いときは、まず無駄な集約項目をGROUPBYから外すことから始めましょう。

データの抽出に時間がかかっている場合は通常のSELECT文と同じようにチューニングします。

SQLのチューニングは↓で詳しく解説していますので参考にしてください。
>>SELECT文のSQLチューニング方法まとめ