SQLチューニングの必須知識を総ざらい(前編)Oracle SQLチューニング講座(2)(2/2 ページ)

» 2004年07月21日 00時00分 公開
[加藤猛株式会社アゲハ]
前のページへ 1|2       

レコードへのアクセス方法

 表のレコードにアクセスするためのアクセス経路をアクセス・パスと呼び、代表的なものとして全表スキャン索引スキャン、そしてROWIDスキャンがあります。

 効率的な索引が存在するにもかかわらず、「すべての表データを読み込む」などのアクセス・パスが選択されてしまった場合には、アクセスするデータ・ブロック数が増加することで、大きくパフォーマンスが劣化してしまう可能性があります。

 ここでは、チューニングという観点から、全表スキャン、索引スキャン、そしてOracleで最も効率的なアクセス方法であるROWIDスキャンについて説明します。

全表スキャン

 全表スキャンは、必ずHWM注2 までのすべてのデータ・ブロックにアクセスしてすべてのレコードを読み込み、指定された条件にマッチするかの判定を行います。この方法は、表へのアクセス方法の中で最も基本となるものです。

注2HWM

High Water Mark(最高水位標)の略称で、過去に最もデータが挿入された位置を表す。例えば、過去に100万件のレコードが格納され、現在は0件であったとしても、100万件のレコードが挿入されたことのあるデータ・ブロックまですべてにアクセスする。


 本に例えると、知りたい情報(行)を探すために、必ず最後のページまで目を通すことになります。ここで、仮に1ページ目に知りたい情報が書かれていたとしても、最後まで目を通すことになる点に注意が必要です。

 全表スキャンは複数のデータ・ブロックをまとめて読み込むため、表の大部分のレコードを抽出する場合は、効率的なアクセス方法となります。図4が全表スキャンのイメージです。

図4 全表スキャン 図4 全表スキャン(クリックで拡大します)

ROWIDスキャン

 ROWIDスキャンは、Oracleで最も高速に目的のレコードにアクセスする方法です。ROWIDとは、データベース内の「どのデータ・ファイルの、何番目のデータ・ブロック中の、何番目のレコード」といったレコード位置を表す、Oracleの内部的な表現です。条件にこのROWIDを指定してアクセスすると、直接目的のレコードを含むデータ・ブロックへアクセスすることができます。

 本に例えると、知りたい情報がどのページのどの行にあるかをあらかじめ覚えており、直接そのページを開くことになります。

 ROWIDスキャンは非常に効率的ですが、ユーザーにとって意味を持たない文字列のため、覚えておくことは不可能ですし、またExport/Importや表の移動(alter

table moveコマンド)などによってROWIDは変わってしまうため、検索条件として指定することは現実的ではありません。直接ROWIDを使用してアクセスするケースとしては、アプリケーションでいったん取得したレコードに再度アクセスする場合などに限定されてきます。図5がROWIDスキャンのイメージです。

図5 ROWIDスキャン 図5 ROWIDスキャン(クリックで拡大します)

索引スキャン

 索引スキャンとは、索引を読み込んでROWIDを取得し、そのROWIDを使用してデータにアクセスする方法を指します。索引にもいくつか種類がありますが、ここでは最もよく利用されるB*Tree索引を例に説明します。B*Tree索引は、ソートされた索引列のデータと、対応するROWIDを保持しています。条件式に索引列が指定されていると、索引を読み込んでROWID情報を取得し、そのROWIDを使用して表のレコードにアクセスします。

 本で例えると、巻末にある索引を見てページ番号、行番号を調べ、該当のページを開くことになりますので、非常に効率的で現実的な方法であるといえるでしょう。

 図6はB*Tree索引を使用した場合の索引スキャン動作です。この例のように一意性、もしくは選択性の高いカラムに対して索引スキャンを行った場合、索引をたどるための数ブロックと、実際のレコードが格納されているデータ・ブロックへのアクセスのみで、目的のレコードを取得できます。

図6 B*Tree索引スキャン 図6 B*Tree索引スキャン(クリックで拡大します)

 索引スキャンでは、「索引ブロックの読み込み+データ・ブロック」の読み込みとなるため、表からある程度以上の割合を抽出する場合には全表スキャンの方が効率的になる可能性があることに注意してください。一般的に、検索したいレコード件数が、レコード全体の5〜15%程度までの場合は、索引スキャンの方が効率的といわれています。

 また、索引が作成された列のデータを更新すると、索引も自動的にメンテナンスされるため、極端に多くの索引を作成すると更新処理のパフォーマンスに影響を与える可能性があることも忘れないでください。あまり使用されない索引や、パフォーマンス的に効果の薄い索引を削除することも検討すべきでしょう。

 さらに索引には、B*Tree以外にもビットマップ索引や、関数索引など、データの構成や用途に応じて何種類かありますが、すべて目的のレコードのROWIDを効率的に取得できる構造となっています。このように表にアクセスする方法を理解することで、適切なスキャンの選択を行い、パフォーマンス向上を図ります。


 次回は引き続きSQLチューニングに必要な基礎知識として、結合処理とヒントに関して説明します。


前のページへ 1|2       

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。