ここでは、否定形(is not null)を使ったSQLをチューニングする方法を紹介します。
否定形のSQLとは
否定形とは、is not nullやnot inなど、WHERE句でNOTを使った条件を使ったSQLをさします。
他にも、!=や<>など~以外のような条件を使ったSQLです。
否定形のSQLの注意点
上記で説明した、否定形のSQLではインデックスが使用されません。
例えば、
select * from test1 where col1 is not null
というSQLの場合、col1にインデックスが作成されていてもインデックスが利用されません。
インデックスが利用されないことにより、テーブルがフルスキャンされることがあったりするので、処理速度の悪化につながる恐れがあります。
否定形のSQLのチューニング方法
ここからは否定形のSQLのチューニング方法を紹介します。
否定形のSQLをチューニングするには、否定形をやめる必要があります。
否定形をやめる
例えば、empテーブルのbusyo_cdが10,20,30,40,50,nullのとき、null以外のデータを取得する場合です。
・否定形の場合
select * from emp where busyo_cd is not null;
・否定系をやめた場合
select * from emp where busyo_cd in (10,20,30,40,50);
とすることで、null以外の値を条件に指定することで否定形をやめることが出来ます。
他にも、select * from emp where busyo_cd =10 or busyo_cd =20・・・とすることもできます。
ここでいうbusyo_cdの値の数が、10種類や20種類に渡る場合は、INの条件やORで指定すると読みづらくなってきます。
指定する条件が多い場合は、1つのデーブルに対象となるコードをまとめて登録しておくなど工夫すると良いと思います。
select * from emp where busyo_cd in (select busyo_cd from taisyo_busyo)と言った具合に、taisyo_busyoテーブルに対象となるコードをまとめて登録しておけば、いちいちコードを指定する必要もなくなり、コードもスッキリします。
否定形をやめなくてもいい場合
否定形を止めなくていい場合もあります。
→インデックス検索よりも全表検索が速い場合があります。
例えば、従業員マスタのテーブルに上司コードというカラムがあるとします。従業員マスタから、上司コードが設定されているデータを検索します。
・従業員マスタのデータ件数:100,000件
・上司コードが設定されているデータ件数:99,000件
・上司コードが設定されていない件数:1000件(1%)
このとき、select * from 従業員マスタ where 上司コード is not nullとして検索した場合、きっと全表検索(テーブルフルスキャン)されますが、99%のデータは条件に合致するデータのなので、フルスキャンする方が速くなります。
逆に、1%のnullデータを探すためにインデックス検索をする方が、処理に時間がかかります。
極端な例ですが、否定形で除外したいデータの割合によっては全表検索が速くなる場合があります。
最後に
否定形の条件がSQLの遅い原因だと思って、必死にチューニングしてみたけど、実は別のところに原因があったということは良くあります。
また、アプリケーションの仕様的にすぐに否定形の条件をやめるということが難しい場合も多々あります。そのときは他の条件やチューニングできる箇所を探すほかありません。
SQLのチューニングについては、「SELECT文のSQLチューニング方法まとめ」で詳しく解説していますので、ぜひ参考にしてください。