SQLを使ったことがある人ならわかると思いますが、SQLは書き方、使い方によって
実行スピードがかなり変わる場合があります。
実行スピードが遅いなどでSQLの見直しなどしたことがあると思います。
SQLのチューニングとして気を付ける点など上げていきます。
具体的なチューニング手段
- インデックスの作成
SQLのチューニングとしてまず思い付くのがインデックスの作成だと思います。
作成したSQL文の条件式で使用している項目へインデックスが作成されているか確認してみてください。
インデックスを作成すれば、基本的にはパフォーマンスが向上しますが、作成してもパフォーマンスの
向上が見込めないケースがあります。
・WHERE句の検索条件にほとんど使用されない列
検索条件にほとんど使用されない列に対してインデックスを作成しても、効果はありません。
逆に、作成したことによってパフォーマンスの低下を招く恐れがあります。インデックスを作成すると、
インデックスを作成した列のデータを更新した際に、インデックスそのものも更新されるからです。
したがって、検索条件にほとんど使用されない列で、かつ更新頻度が過剰な列に対してはインデックスを
作成しないことをお勧めします。
・検索条件に該当するデータが大量にある場合
インデックスは、大量のデータから 1~ 数百件のデータを取り出すときに最も効果があります。
検索条件に該当するデータが大量にある場合には、インデックスの効果が得られません。
上記のような例もありますので、インデックスの作成はよく考えてから行ってください。
- IN句でのサブクエリ
NOT INやIN句を使用したサブクエリは可能な限り、EXISTS、NOT EXISTSを使用したほうがいい。
IN句を使用した例
SELECT name FROM Personnel WHERE birthday IN (SELECT birthday FROM Celebrities);
EXISTS句を使用した例
SELECT P.name FROM Personnel AS P WHERE EXISTS (SELECT * FROM Clelebrities AS C WHERE P.birthday = C.birthday);
- 不要な結合、不要なDISTINCT
あるテーブルにあるかどうか、ないかどうかを実現するためだけにJOINをして
結果をDISTINCTするSQLをみたことがありますが、大変無駄なのでEXISTS、NOT EXISTSを使用すること。
遅い例
SELECT a.name FROM shain a, (SELECT DISTINCT shain_id FROM sikaku WHERE sikaku_name IN ('基本情報','java') ) b WHERE a.shain_id = b.shain_id;
速い例
SELECT a.name FROM shain a WHERE EXISTS (SELECT ‘X’ FROM sikaku b WHERE sikaku_name IN ('基本情報','java') AND a.shain_id = b.shain_id);
- 左辺の関数
条件では列側に関数は使用しない。インデックスが使用されない。
遅い例
SELECT a.name FROM shain a WHERE to_char(a.birthday,’YYYY/MM/DD’) = ‘2000/03/21’;
速い例
SELECT a.name FROM shain a WHERE a.birthday = to_date(‘2000/03/21’ ,’YYYY/MM/DD’);
- その他
・UNIONよりUNION ALL
重複行を排除するためのソートが発生するので、重複を許すのであればUNION ALLを使う。
・IS NULLはなるべく使わない
・NOT IN、!=、<>はなるべく使用しない
NOT EXISTS、ORやINで代用できるならする。工夫しても無理なら使ってもよいと思う。
他にも方法はたくさんあるかもしれませんが、よくある例としてあげてみました。
効果的なものからそうでもないものまであると思いますが、少しでも動作が早くなるよう
工夫を重ねていくことが大事だと思います。