SQLチューニングの基礎の"そ"(SQLServer編)

どうも!三和システムおちゃらけ担当のuozy☆です!

今日は恒例のゴルフエンジニアのゴルフ練習の日です!
業務後にゴルフエンジニア達で近くのゴルフ練習場へ行きます!
ゴルフシステムを作るエンジニアだからこそゴルファーの気持ちを知らないとね\(^o^)/


今回のテーマ

前回は遅くなったクエリを見つけるところまでの記事を書きましたが、
今回はクエリの高速化の基本と勘所を書きたいと思います。

まずは実行プランの見方

ざっくりわけると2種類あります。

scan

f:id:uozy:20150130173637p:plain

seek

f:id:uozy:20150130173646p:plain

じゃ、どっちがいいの?

  • scan
    →これはいわゆる"走査"というやつです。
     どんな動きかというのを例えると、
     辞書で単語を探す時に「あ」から一語一語単語を調べていくイメージです。
     つまり効率的には最低です(´・ω・`)

  • seek
    →この人が最速、圧倒的です \(^o^)/
     索引を効率的に使って探してる単語のページをぱっと開ける感じです。

という事で、基本的に最速なのはseekです!
もう今日はこれだけを覚えてください!
遅いクエリを見つけたらとにかくseekを目指しましょう!!

どうしたらseekになるの?

これについては場合によりけりなのでこうしたらっていうのはないです。
そこで大公開!
uozy☆的基本方針

  • 不要なカラムのselectをやめる
  • 抽出条件を見直して本当に必要な行だけ対象になるようにする(selectivityの問題)
  • 巨大なテーブルをいくつもjoinしない(巨大なテーブルを扱う際は一時テーブルに切り出す)
  • テーブル変数(@table)より一時テーブル(#table)を使う
    (テーブル変数では並列処理してくれません)
  • 見やすいように書く(人間が読みにくいコードは機械も読みにくいと信じてますw)
  • 極力cursorを使わない(何でもループすればいいってもんじゃない)

勘所!!

さらに勘所まで大公開!!

  • select * を使わない
    →これ、いまだにたまに見かけます(`・ω・´)
     せっかくindexで行を見つけてもindex外の不要なデータも一緒に取得する為に
     key参照が発生します。
     しかも全カラムを取得するのはメモリやDiskI/O等のリソースのムダだし
     何よりかっこ悪すぎるのでやめましょう!

  • 条件句の左辺に関数を使わない
    →これもね。。。
     関数かましたらindexで探せないでしょうorz

  • 暗黙の型変換
    →これ、seekしかないのに遅い!って時にチェックしてみてください。
     例えばwhere句で指定してる条件での左右のデータ型が一致していない場合、
     どっちかのデータを暗黙的に型変換してから比較をするわけです。
     テーブルに1行しかないなら別にいいんですが、
     これが100万行・1億行となると・・・。
     特にこのパターンでよくあるのはvarcharとnvarcharです。

次回は

これで低速なだっさいクエリとはさよならできましたね?
クエリ書くならやっぱ速い方がかっこいいよね!

次回は・・・まだ決めてませんw

バイバーイ\(^o^)/

あ、そうそう。
ゴルフ練習に参加したい方はuozy☆まで!