はじめに
OracleのDB関連の仕事で、SQLのパフォーマンスチューニングをしていた時に、
実行計画を見る機会が多かったので、
簡単ではありますが実行計画について記事を書きました。
今回は、パフォーマンスチューニングをする上で重要となってくるインデックスを
使用した時と使用しない時で実行計画がどう変わってくるのかを見てみました。
インデックスとは?
データにアクセスするための目印で、本でいうところの目次のようなものです。
インデックスを作成することで、SQL実行時の処理時間を短縮させることが出来ます。
DBのバージョン
今は12cもあって11gはちょっと古いかもしれませんが、
下記のバージョンで確認しています。
- Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production
ツール
SQLplusを使用しています。
#準備
テーブル
今回は、SQLの研修などでよく使われるEMP表を用意しました。
DESC emp;
データ
レコード数が少ないと実行計画に差が出なさそうなので、
10万件ほど用意しました。
SELECT count(1) FROM emp;
インデックス作成
ENAME(従業員名称)にインデックスを貼ります。
CREATE INDEX emp_ename_ix1 ON emp(ename);
実行計画
実行計画とは
ユーザが発行したSQLを実行するための計画書・手順書のようなものです。
テーブルの結合方法や使用するインデックスの選抜などをします。
実行計画は、オプティマイザと呼ばれるものが作成し、
基本的に最適な実行計画を作成してくれますが、
複雑なSQLの場合、必ずしも100%最適とは限りません。
そのため、人が目で実行計画を見て、改善点がないかを検討するための材料として使われます。
実行計画を見る方法
AUTOTRACEを実行することで実行計画を取得できます。
SET AUTOTRACE ON
実行計画を確認
先ほどのようにAUTOTRACEをONにしたら、実際にSQLを実行して実行計画を確認してみます。
今回はENAMEが「JONES」のレコードを取得するSQLを実行します。
- 実行するSQL
SELECT * FROM emp WHERE ename = 'JONES';
インデックスを使用する場合
一番上がSQLの実行結果になります。ENAMEが「JONES」のデータが1レコード取得できていることが分かります。
その下に表示されているのが実行計画になります。
赤枠で囲っているid=2の行が「INDEX RANGE SCAN」となっており、
さらにName列が「EMP_ENAME_IX1」となっているので、
最初に作成したインデックスが使用されていることが分かります。
Cost列を見ると、id=2の行は「1」となっていて少ないコストで済んでいることが分かります。
このように、オプティマイザはCostができるだけ小さくなる実行計画を作成します。
次にインデックスを使用しない場合どうなるか見てみましょう。
インデックスを使用しない場合
ヒント句を使って、インデックスを使わせないようにすることもできますが、
分かりやすくするためにインデックスを削除します。
DROP INDEX emp_ename_ix1;
インデックスが無い状態で先ほどと同じSQL文を実行します。
実行計画は下記のようになりました。
実行結果は同じように1レコード取得されています。
実行計画を見ると、id=1が「TABLE ACCESS FULL」となっています。
これは、テーブルの全レコードを検索しているという意味です。
Costも「182」と大きくなっていることが分かります。
まとめ
単純なSQLではありますが、インデックスを使用した時の方が、
SQLのコストが低くなっていることが分かりました。
次回
次回以降は、インデックスの仕組みの詳しい説明、もしくは実際にパフォーマンスチューニングをする際の具体的なアプローチの仕方などを紹介できればと思います。