SAKURUG TECHBLOG

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

timestampauthor-name
Kenji

はじめに

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

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

どんな人向けか

  • データベースでオブジェクト(表や索引等)を作成することがある
  • そもそも索引って、何を条件に作成していいかわからない
  • 処理内等で SQL を実行するが、結果応答(レスポンス)が遅い気がする

前提条件

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

心得

 データベースにおいて、実務上よくパフォーマンス劣化に陥りやすいのが、索引スキャンであることが多い気がします。

 索引とは?という方は、下記のページを参考にしてみてください。

 初心者のためのデータベース索引付けの概要

 そんなパフォーマンス劣化を防ぐためにも、索引作成時に主な次の3点を考慮すると、索引が有効に働き、パフォーマンスの向上につながります。

条件① ある程度のレコード件数が格納されている表であること

 表にある程度のレコード件数が格納されていなければ、表フルスキャンの方が早いです。ある程度の目安としては、10,000 件程を指しています。

条件② WHERE 句で指定される列であること

 WHERE 句で指定されない列に対して索引を作成しても効果はありません。ただし、一意制約や主キー制約のための一意索引はこの限りではないです。

条件③ WHERE 句に指定される絞り込み条件により全体レコードの 10% 以下が返される列であること

 WHERE 句で指定される列であっても、その絞り込み条件により返されるレコード数の割合が大きいと、索引アクセスによる読み込みデータ量の低減効果は望めません。場合によっては、複数のデータ量をまとめて読み込むことのできる表フルスキャンの方が SQL の処理時間が短くなることもあります。

 目安として、WHERE 句に指定される絞り込み条件により全体レコードの 10%以下が返される列に索引を付与することで、索引によるパフォーマンスの向上が図れます。

 以上、3つの条件を考慮し、索引作成することを普段心がけています。

事例

 次のような会員表に対する SQL が実行されるとき、前述した3つの条件を考慮したうえで、どの列に索引を付けるべきでしょうか?

select 名前, プラン
  from 会員表
 where 名前 = '東京 花子'
   and プラン = 'スタンダード'

 まず、条件①「ある程度のレコード件数が格納されている表であること」を考えます。図にある説明では「総レコード数は、100,000 件」とあることから、十分なレコード数が格納されていることが分かるため、会員表に対して索引を作成する余地があると判断できます。

 次に条件②「WHERE 句で指定されることが多い列である」を考えます。SQL の WHERE 句で指定されている列は [名前] 列と [プラン] 列の 2 列です。索引を付けるべき列の候補として、この 2 列が考えられます。

 最後に条件③「WHERE 句に指定される絞り込み条件により全体レコードの 10% 以下が返される列である」を考えます。参照している会員表の総レコード数が 100,000 件なのに対し、 [名前] 列には 90,000 種類、 [プラン] 列には 2 種類のデータが含まれているとあります。

 仮に次の SQL を実行した場合、

select 名前, プラン
  from 会員表
 where 名前 = '東京 花子'

90,000 種類から残りの 10,000 件全ての名前が「東京 花子」だとしても、返されるレコード数の割合は、総件数の 10% 以下です。

では、[プラン] 列のみで絞った場合を考えた場合、

select 名前, プラン
  from 会員表
 where プラン = 'スタンダード'

余程の偏り( 「スタンダード」プランの会員のみしかいない場合とか )がない限りは、10% 以下に絞られることはないでしょう。

 したがって、すべての条件をクリアした [名前] 列に索引を付与することが望まれます。

さいごに

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

 上記のように必ずしもそれに従っていれば最適であるというわけではありませんが、索引作成時の基礎的な考えを紹介させて頂きました。

 なかなか、パフォーマンス性能をチェックすることは実務に携わってから学ぶことが多いのが現状かと思うのですが、逆を言えば実務に携わる前に知れる機会があれば、もっと根本的な処理や機械的な動作の仕組みから知れることになるため、強力な自分の武器となると言えるのではないでしょうか。

 私自身もコード設計や開発していた頃は、見よう見真似で SQL を書いていましたが、データベースをメインに業務していると、かなり奥が深い世界だということを痛感しております。

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

参考文献

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

記事をシェアする

ABOUT ME

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