SAKURUG TECHBLOG

SQL チューニング - 索引編②

timestampauthor-name
Kenji

はじめに

 本稿では、私が普段の現場業務で使用しているデータベースから、 索引(インデックス)作成時に心得ておきたい事項を記載しています。

 学科やプログラミングを独習するだけでは、なかなか知識として得られない、かつ私自身にも役立てている内容を紹介させて頂ければと思います。

どんな人向けか

  • データベースでオブジェクト(表や索引等)を作成することがある
  • 索引を作成してみたものの、作成前と結果応答(レスポンス)が変わらない気がする

前提条件

 本稿では、Oracle Database 11g Release 2 を対象としています。

心得

 以前に、『SQL チューニング - 索引編① 』をご紹介させて頂きましたが、今回はその②と言うことで、

 検索の処理性能を向上する目的で、むやみに索引を作成しても、その効果を得られる可能性が低いケースがあります。

 そんな効果を発揮しない主なケースを5つを紹介し、索引作成あるいは SELECT クエリ実行時の役に立てて頂ければと思います。

効果を発揮しないケース① WHERE 句内の計算式や関数に索引列が利用されている

 たとえば、次のような SQL が実行される場合

select 型番, 商品名
  from 在庫
 where 販売数 + 10 > 100 

 「販売数 + 10」 という演算結果と「100」を比較しているため、内部で販売数列を計算した結果で判定します。結果として索引が機能せず、表フルスキャンになる可能性が高くなります。

 下記の SQL の様に関数を利用した場合でも同様の判定となります。

select 型番, 商品名
  from 在庫
 where to_char(販売日, 'YYYYMMDD') = '20250930'

回避策

 1つ目の場合の回避策としては、次の SQL のように変更することで、索引列(販売数)そのものと比較するため、索引が利用される可能性が期待されます。

select 型番, 商品名
  from 在庫
 where 販売数 > 100 - 10

 また、2つ目の場合の回避策としては、索引列と比較する側を操作することで、索引が利用される可能性が高まります。

select 型番, 商品名
  from 在庫
 where 販売日 = to_date('20250930', 'YYYYMMDD')

効果を発揮しないケース② 索引列が後方一致や中間一致の LIKE 検索で利用されている

 索引は昇順、降順にデータが並べられて格納されているため、「where COL1 like 'Oracle%'」(前方一致)のような LIKE 検索では索引が利用されますが、「where COL1 like '%Oracle'」(後方一致)や「where COL1 like '%Oracle%'」(中間一致)のような LIKE 検索を利用した場合は、索引が利用されない可能性が高いです。

-- NG ①
select 型番, 商品名
  from 在庫
 where 商品名 like 'コードレス%'

-- NG ②
select 型番, 商品名
  from 在庫
 where 商品名 like '%コードレス%'

効果を発揮しないケース③ 索引列に対して IS NULL や IS NOT NULL の条件が利用されている

 索引に NULL 値は格納されません。したがって「where COL1 is null」や「where COL1 is not null」のような NULL 値に対する判定条件では、該当データが索引に含まれていないため、表フルスキャンになる可能性が高いです。

-- NG ①
select 型番, 商品名
  from 在庫
 where 販売日 is null

-- NG ②
select 型番, 商品名
  from 在庫
 where 販売日 is not null

効果を発揮しないケース④ 索引列に対して NOT 条件が利用されている

 「where not (SALARY >= 10000)」や「where DEPTNO != 10」のような否定(NOT)条件が利用されている場合、単純に「指定した値以外全部」と範囲特定が曖昧になるため、結局大分部のデータを走査することになり、表フルスキャンとなる可能性が高いです。

効果を発揮しないケース⑤ 単一の表に対して作成する索引の数は 6 つ程度まで

 表データが更新されると同時に索引のデータ更新も内部で行われます。したがって、索引の数が多いとそれだけ更新処理に大きなオーバーヘッドが生じるため、単一の表に対して作成する索引の数は 6 つ程度に抑えるとよいです。

 以上のことを考慮し、索引作成あるいは SQL を記述することを私自身も心掛けています。

さいごに

 いかがでしたでしょうか。

 検索処理性能が向上するからと、ただ闇雲に索引を作成しただけでは、効果が得られないケースがあるということを理解して頂ければ幸いです。

 実際に索引が想定通りに動作しているかは、実行計画(DBMS_XPLAN)等で確認することが大事であると、私自身も業務を通じて実感いたしました。

 開発するうえで、何かの一助になれば幸いです。

参考文献

 『 即戦力の Oracle 管理術 ~仕組みからわかる効率的管理のノウハウ 』

▼高校生向けインターン実施中!

弊社では高校生向けにインターンを行っております!
現役エンジニア指導の下、一緒に働いてみませんか?

高校生インターン応募フォーム

▼カジュアル面談実施中!

カジュアル面談では、会社の雰囲気や仕事内容についてざっくばらんにお話ししています。
履歴書は不要、服装自由、原則オンラインです。興味を持っていただけた方は、
ぜひ以下からお申し込みください。

皆さんにお会いできることをサクラグメンバー一同、心より楽しみにしております!

カジュアル面談応募フォーム

記事をシェアする

ABOUT ME

author-image
Kenji
2017年に中途入社。趣味は映画鑑賞・漫画(読む方)・ゲーム等々。「そろそろ運動して痩せなきゃ!」が口癖!?