はじめに
実務でSQLチューニングを行う際、同じPJ内の方にチューニング説明をする機会が度々あったので、個人用含め手順についてまとめていきます。
手順
・実行計画を取ろう
・いきなりインデックスはちょっとまって
・絞り込みはHAVING句よりWHEREよりFROM
・その他TIPS
・インデックスについて
・それでも改善しない
実行計画を取ろう
はじめは実行計画を取ります。理由として、実行計画は対象SQLのどこが早く、どこが遅いかをすぐに教えてくれるからです。闇雲に条件を変えたりインデックスを貼ったりすると横展開の被害が大きくなるので大変になります。
SQLの実行計画の読み方
パフォーマンスチューニング9つの技 ~「探し」について~
いきなりインデックスはちょっとまって
SQLチューニングといえばインデックス?ですが、インデックスには効率的な付与の条件がいくつかあります。逆にいうと非効率な付与を行うと実行計画が変わり、最悪の場合他のSQLも処理が遅くなってしまいます。
インデックスについて検索すると”大規模なテーブルに付与するのがいい”など出ますが、大規模なテーブルは他にも多くのSQLを使っているので注意が必要です。
絞り込みはHAVING句よりWHEREよりFROM
詳しい理由は他にもあると思いますが、条件の絞り込みはSQL実行の早い段階で大きく絞り込めていれば絞り込めているほど後続処理が小さく済むので、
HAVING句に条件があればWHEREに移動できないか、またWHEREに書いてある条件はFROM(結合条件)に移動できないか検討してみてください。
その他TIPS
- サブクエリを引数に取る場合、INよりもEXISTSを使う※1
- サブクエリを引数に取る場合、INよりも結合を使う※2
- ソートを回避する※3
- DISTINCTをEXISTSで代用する※4
- 中間テーブルの代わりにHAVING句を活用しよう※5
- IN述語で複数のキーを利用する場合は、一箇所にまとめる※6
インデックスについて
(ヒント句とかは置いといて)最終手段インデックスに書いていきます。
- どこにインデックスを付与するか※7
- 1.主キー
- 2.外部キー
- 3.絞り込み対象
- 4.集計対象
- 5.ソート対象
- どのようにインデックスを付与するか
- 大規模テーブル
- ※小規模テーブルの改善で処理速度が許容範囲になるなら、二次被害を防ぐために個人的には小規模テーブルから見るのがおすすめです
- カーディナリティが高い
- 大規模テーブル
- インデックス付与されないパターン
- 加工をしている
- NULLを使っている
- 否定形を使っている
- 複合インデックスと列の順番が異なる
- 後方一致、曖昧条件を使っている
インデックスを付与しても結合条件が異なったりするので注意が必要です。
結合方法について下記お世話になってます。
チューニング ~ SQLチューニングを実施する ~
それでも改善しない
上記色々試しても望む改善がされない場合、ヒント句や並列実行の処理方法がありますが、
SQLを使ってるバージョンやその他機能との依存関係になってしまうので、SQL以外の改善方法(マテビュー作成や機能の並列処理など)を見直した方がよいかなと個人的には思います。
参考
- ミック (2018/10/11) 「達人に学ぶSQL徹底指南書 第2版 初級者で終わりたくないあなたへ」※1~6
- NAOKI MATSUMOTO (2024/9) 「【22日間で学ぶ】SQL文、分析関数、テーブル設計、SQLチューニングまでMySQLで覚えるSQL実践講座」※7