インデックスが効かないSQLはパフォーマンスが遅い
インデックスが効かない原因
Oracleでパフォーマンスが遅いのにはいくつかの理由があります。
パフォーマンスが遅い理由で最も多いのが「SQLの問題」です。SQLを改善すれば、パフォーマンスがよくなって検索時間を短縮できる効果が高いです。
どういうケースがパフォーマンスが低いのか?
順番に説明します!
ちなみにデータベースの状態によってはパフォーマンスが改善されないこともあります。必ずというわけではありませんので、ザックリとした知識として覚えておくといいですね。
例1. NULL は遅い
-- nullは遅い SELECT * FROM emp WHERE empname IS NULL; -- not nullは遅い SELECT * FROM emp WHERE empname IS NOT NULL;
ここではWHERE句の条件に「NULL」、もしくは「NOT NULL」にしています。「NULL」を使うとインデックスが使われないため、パフォーマンスが悪くなってしまいます。
例2. NOT(!=)は遅い
-- !=は遅い SELECT * FROM emp WHERE empno != 'A0001';
ここではWHERE句の条件に「!=」、つまり「NOT =」のことですね。「!=」を使うとインデックスが使われないため、パフォーマンスが悪くなってしまいます。
例3. OR は遅い
OR の遅い例
-- ORは遅い SELECT * FROM emp WHERE empno = 'A1000' OR empno = 'B1000';
ここではWHERE句で「OR」を使っています。「OR」を使うとインデックスが使われないため、パフォーマンスが悪くなってしまいます。
OR のパフォーマンス改善例
-- ORのパフォーマンス改善例 SELECT * FROM emp WHERE empno = 'A1000' UNION ALL SELECT * FROM emp WHERE empno = 'B1000';
「OR」で条件指定するのはやめて、「UNION ALL」で複数のSQLを結合すれば同じことができます。こちらの方が高パフォーマンスです。
例4. IN は遅い
IN の遅い例
-- INは遅い SELECT * FROM emp WHERE empno IN ('A1000','B1000');
ここではWHERE句で「IN」を使っています。「OR」と同様、「IN」を使うとインデックスが使われないため、パフォーマンスが悪くなってしまいます。
IN のパフォーマンス改善例
-- INのパフォーマンス改善例 SELECT * FROM emp WHERE empno = 'A1000' UNION ALL SELECT * FROM emp WHERE empno = 'B1000';
「IN」で条件指定するのはやめて、「UNION ALL」で複数のSQLを結合すれば同じことができます。こちらの方が高パフォーマンスです。
例5. 演算 は遅い
演算の遅い例
-- 演算は遅い SELECT * FROM emp WHERE score * 100 > 50;
ここではWHERE句で「score * 100」と演算しています。演算するとインデックスが使われないため、パフォーマンスが悪くなってしまいます。
演算のパフォーマンス改善例
-- 演算のパフォーマンス改善例 SELECT * FROM emp WHERE score > 0.5;
演算した結果で比較すれば高パフォーマンスとなります。
例6. 複合インデックスの順番を無視 は遅い
インデックスを使用しない例
-- インデックスは{score1,score2}で作成済み CREATE INDEX idx1 ON emp (score1 ,score2); -- インデックスを使用しない例 SELECT * FROM emp WHERE score2 > 1;
まずインデックスが{score1,score2}で作成されていたとします。複合列でのインデックスです。この順番が重要です。
ここで 「score2」単独での検索ではインデックスがききません。インデックスは{score1,score2}であるため、「score1」か「score1,score2」はインデックスを使用しますが、「score2」はダメです。
インデックスを使用する例
-- インデックスを使用する SELECT * FROM emp WHERE score1 > 1; -- インデックスを使用する SELECT * FROM emp WHERE score1 > 1 AND score2 > 5;
「score1」もしくは「score1,score2」の順番であればインデックスを使用します。
以上、Oracleでパフォーマンスが遅い理由として、インデックスを使用しないSQLを紹介しました。
コメント