SQLチューニングの基礎
SQLチューニング
SQLは、表や列の名前を指定すれば簡単にデータへアクセスできる便利な言語です。
RDBMSはオプティマイザというコンポーネントを持っており、
このオプティマイザがクエリ (データに対する問い合わせ) を実行する最も効率的な方法を決定するようになっています。
今は、コストベースのオプティマイザ(CBO:Cost-Base-Optimizer)が主流で、
ORACLEやSQL Server などがコストベースのオプティマイザ(CBO)を採用しています。
従って、基本的には、CBOに基づいたチューニングを行うのがベストです。
しかし、
「そこまでは〜」という方もいると思うので、
最低限抑えておきたい、速度改善のSQLチューニングを5つご紹介したいと思います。
速度改善のSQLチューニング 5選
- SELECTに不要なカラムを含めない
- 巨大なテーブルをいくつもJOINしない
- INでサブクエリを使わない
- Whereに関数を含めない
- 引数リストは左寄せ
これは皆さんご存知のチューニングの王道です。
SELECT * FROM 顧客マスタ WHERE 条件
なんてやっちゃうと、せっかくindexで行を見つけてもindex外の不要なデータも一緒に取得することになり、
key参照が発生します。
SELECT CODE, NAME, ADDRESS, TEL FROM 顧客マスタ WHERE 条件
などのように、必要な項目だけをSELECTするようにしましょう。
顧客に対して売上伝票をJOINするような事がよくあります。
SELECT K.code, K.name , U.ddate, U.dno, U.suu, U.uriagekin FROM 顧客マスタ AS K INNER JOIN 売上伝票 AS U
毎日、この顧客マスタに数百件、売上伝票に数千件のデータが増えていくと考えると、
100×1000、200×2000、300×3000とデータ量が膨大になっていく度に、
上記のSELECTのレスポンスは非常に悪くなっていきます。
こういった事を予測し、売上伝票を日付条件で絞り込んでおけば安心です。
また、その絞り込んだ結果を一時テーブル(#table)に切り出しておき、それをJOINすることで、
さらに快適なレスポンスを得られるようになります。
not inやin句を使用したサブクエリは全走査対象となるため、
exists、not existsを使用した方がIndexを使用されやすくなりレスポンスが良くなります。
Where条件では列に対して関数を使うとIndexが利用されなくなります。
例えば、2000万行のデータで強引にCONVERT関数をかましてみると、
平均で3000ミリ秒かかります。
SELECT DNO FROM TD_MITUMEISAI where CONVERT(varchar,KIN)>='10000'
しかし、関数をかまさないで実行すると、平均で2000ミリ秒です。
SELECT DNO FROM TD_MITUMEISAI where KIN>=10000
これだけで1.5倍の差がでるわけです。
IN句の引数リストを用いる場合、要素を検索される事が多い順に左寄せにします。
(例)
SELECT * FROM Address WHERE prefecture IN ('東京', '神奈川', '京都', '大阪', '千葉', '名古屋', '福岡');
全国を対象にする場合、人口の多い順に並べると効果が出ます。
意外と知られていないテクニックです。
まとめ SQLチューニングを心がけてコーディング
単純にまとめちゃうと、
上記5つを理解しSQLを書いておくことが大切です。
逆に言えば、基本的なチューニング方法なので、できてないと恥ずかしい...
「SELECTに不要なカラムを含めない」「巨大なテーブルをいくつもJOINしない」「INでサブクエリを使わない」「whereに関数を含めない」「引数リストは左寄せ」
もっと覚えやすい見出しにしたかったのですが、これ以上短くすると意味わからなくなるので、ごめんなさい。
とにかく、「SELECTに不要なカラムを含めない」「巨大なテーブルをいくつもJOINしない」「INでサブクエリを使わない」「whereに関数を含めない」「引数リストは左寄せ」です。