小池啓仁 ヒロヒト応援ブログ By はてな

小池啓仁(コイケヒロヒト)の動画など。

小池啓仁 ヒロヒト応援ブログ By はてな

SQLを速くするための小技

以下のリンク、『SQLを速くするぞ』を読んでのメモです。

http://www.geocities.jp/mickindex/database/db_optimize.html


全15項目あり、上記のデットリンクや忘れないため、ここにメモしときます。

項目1:サブクエリを引数に取る場合、IN述語よりもEXISTS述語を使う。
理由1:IN述語の全表走査よりも、EXISTS述語の方が効率的に検索。


項目2:BETWEENを使う。
理由2:指定された範囲のインデックスのノードを1回の操作で比較することができる。


項目3:IN 述語の引数リストには、最もありそうなキーを左寄せする
理由3:左から右へ引数を評価するから。


項目4:EXISTS述語のサブクエリ内では、SELECT * を使う。
理由4:オプティマイザにインデックスが張られている列を使うべきかの選択を委ねられる。


項目5:3つ以上のテーブルを結合させる時は冗長な結合条件を書く。
理由5:テーブルのサイズが変わっても大丈夫なように。


項目6:行数を数えるときは COUNT(*) よりも COUNT(列名) を使う。
理由6:ただし、COUNT 関数の引数となる列にインデックスが張られている場合。


項目7:WHERE 句の抽出条件は、最も制限の強いものから並べる。
理由7:選択される行数が少ないものから順に並べる方が、効率よく動作する。


項目8:UNION の代わりに UNION ALL を使う。
理由8:重複を気にしなくてよい場合。(UNION は重複行を排除するためのソートが発生)


項目9:実はインデックスが使用されていないというケースが多々ある。
理由9:

  • 索引列に演算を行なっている。
  • IS NULL 述語を使っている。
  • 索引列に対してSQL関数を適用している。
  • 否定形を用いている。
  • ORを用いている。
  • 後方一致、または中間一致のLIKE述語を用いている。
  • 暗黙の型変換を行なっている。
  • 複合インデックスの場合に、列の順番を間違えている。

項目10:行ポインタによるアクセスが最速。
理由10:しかし、MS-SQL Serverはこの機能はない。


項目11:ワイルドカードは使わない。
理由11:実行時に実際の列名への読替えが発生し、オーバヘッドが増加。


項目12:列番号は使わない。
理由12:列名への読替えが発生するため。


項目13:表に別名を付ける。
理由13:解析時にどの列がどのテーブルに属するかの判定を省略できるため。


項目14:暗黙の型変換を回避する。
理由14:暗黙の型変換は一度代入に失敗した後に行なわれるため、オーバーヘッドが発生。


項目15:ビューを濫用してはいけない。
理由15:集約操作が含まれている場合、非効率的な SQLになる。