最近インデックスについて学んだので、必要なケースで積極的に使うようになりました。でも、速度があんまり変わっていない気がするんです。
実はインデックスを貼っていても、SQLの書き方によっては無効になってしまうケースがあります。これらのケースを押さえておけば、クエリの速度をあげた書き方ができたり、遅いクエリの原因を特定することもできるようになります!
インデックスが効かないケースまとめ
まずは結論から!インデックスが効かないケースは次の6点です。
- 変換してから比較
- 型が違う
- 中間一致と後方一致
- or検索
- null検索
- 否定形
具体的な対策と一緒に見ていきましょう!
変換してから比較
インデックスはあくまで対象となるカラムに対して貼られています。変換した結果に対しては、インデックスが貼られていないので効かないのです。
計算してから比較
効かないケース
SELECT * FROM tables WHERE col_index * 10 > 100;
対策後
インデックスの貼ってあるカラムに対して計算するのでなく、比較する値に対して計算します。
SELECT * FROM tables WHERE col_index > 100 / 10;
関数を利用してから比較
効かないケース
SELECT * FROM tables WHERE ROUND(col_index) > 100;
型が違う
効かないケース
数値型で定義したcol_indexに対して、文字列型で比較している場合です。暗黙の型変換が行われ、エラーは発生しないものの、インデックスが使用されなくなります。
SELECT * FROM tables WHERE col_index = '100';
対策後
比較する値を型変換します。
SELECT * FROM tables WHERE col_index = CAST('100' AS SIGNED);
中間一致と後方一致
中間一致
効かないケース
SELECT * FROM tables WHERE col_index LIKE '%a%';
対策後
LIKE検索を利用する場合は、前方一致のみインデックスが利用できます。
SELECT * FROM tables WHERE col_index LIKE 'a%';
後方一致
効かないケース
SELECT * FROM tables WHERE col_index LIKE '%a';
対策後
LIKE検索を利用する場合は、前方一致のみインデックスが利用できます。
SELECT * FROM tables WHERE col_index LIKE 'a%';
or検索
効かないケース
SELECT * FROM tables WHERE col_index = 1 OR col_index = 10
対策後
WEHER IN を使います。
SELECT * FROM tables WHERE col_index IN (1, 10);
null検索
nullはデータの値とみなされず保持していないためnullを判定する時は、インデックスが効きません。
in null
効かないケース
SELECT * FROM tables WHERE col_index IS NULL;
is not null
効かないケース
SELECT * FROM tables WHERE col_index IS NOT NULL;
否定形
効かないケース
SELECT * FROM tables WHERE col_index <> 100;
まとめ
最後にまとめていきましょう!
- 変換してから比較→変換を比較する側で行う
- 型が違う→比較する値を型変換して一致させる
- 中間一致と後方一致→前方一致のみ効く
- or検索→where in を利用する
- null検索
- 否定形
型を意識していなくて、インデックスが効いていなかったということは起きがちです。どのカラムに対してインデックスを貼るべきか、インデックスが効くSQLが書けているかはしっかり意識していきたいです!ではまた!!
コメント