SQLの性能改善を行う際、実行計画を取得することがよくある。実行計画とは、実際に実行されるプログラムの概要を提示したもので、実行計画によって検索方法(インデックスを使うか使わないか)やテーブル結合方法等を調べることができる。
今回は、SQL Developerというデータベース管理ツールを用いて、Oracleデータベースの実行計画を取得してみたので、その内容を共有する。
前提条件
Oracle XEのインストールが完了し、以下のUSER_DATAテーブルが作成済であること。
1 | desc USER_DATA |
また、USER_DATAテーブルの「ID」に主キー等のインデックスが設定されていること。以下のSQLを実行することで、「ID」にインデックスが設定されていることが確認できる。
1 2 3 4 5 6 | SELECT ai.INDEX_NAME, ai.INDEX_TYPE, ai.TABLE_NAME, ai.UNIQUENESS, uic.COLUMN_NAME FROM ALL_INDEXES ai, USER_IND_COLUMNS uic WHERE ai.INDEX_NAME = uic.INDEX_NAME AND ai.TABLE_NAME = uic.TABLE_NAME AND ai.TABLE_NAME = 'USER_DATA' AND ai.OWNER = 'USER01' |
さらに、USER_DATAテーブルに以下のデータが追加されていること。
1 | SELECT * FROM USER_DATA WHERE ID BETWEEN 1 AND 3 |
インデックス検索を行う場合の実行計画
前提条件で作成済の「USER_DATA」テーブルからID=1のデータを抽出する際、インデックス検索が行われる。その際の実行計画は、以下のSQLを実行することで確認できる。
1 2 | EXPLAIN PLAN FOR SELECT * FROM USER_DATA WHERE ID = 1; SELECT PLAN_TABLE_OUTPUT FROM TABLE(DBMS_XPLAN.DISPLAY()); |
実行計画の結果を確認すると、「TABLE ACCESS BY INDEX ROWID」「INDEX UNIQUE SCAN」とあるので、インデックス検索が行われていることが確認できる。なお、「TABLE ACCESS BY INDEX ROWID」「INDEX UNIQUE SCAN」については、以下のサイトを参照のこと。
https://cosol.jp/knowledge/knowledge_post/sql-execution-plan-table-access-by-index-rowid/
さらに、インデックス検索の種類については、以下のサイトの「インデックスとテーブルへのアクセス」を参照のこと。
https://use-the-index-luke.com/ja/sql/explain-plan/oracle/operations
また、以下のように、実行計画を取得したいSQLを指定した上で「実行計画」ボタンを押下することでも実行できる。
1 | SELECT * FROM USER_DATA WHERE ID = 1; |
インデックス検索を行わない場合の実行計画
前提条件で作成済の「USER_DATA」テーブルからNAME = ‘テスト プリン1’のデータを抽出する際、インデックス検索が行われない。その際の実行計画は、以下のSQLを実行することで確認でき、「TABLE ACCESS FULL」とあるので、インデックス検索が行われずフルスキャンが行われていることが確認できる。
1 2 | EXPLAIN PLAN FOR SELECT * FROM USER_DATA WHERE NAME = 'テスト プリン1'; SELECT PLAN_TABLE_OUTPUT FROM TABLE(DBMS_XPLAN.DISPLAY()); |
また、「実行計画」ボタンを押下した結果は以下の通りで、インデックス検索が行われずフルスキャンが行われていることが確認できる。
1 | SELECT * FROM USER_DATA WHERE NAME = 'テスト プリン1' |
要点まとめ
- 実行計画とは、実際に実行されるプログラムの概要を提示したもので、実行計画によって検索方法やテーブル結合方法等を調べることができる。
- Oracleデータベースの実行計画はSQL Developerを使って取得できる。
- 実行計画を取得するには、EXPLAIN PLAN FOR文で実行計画を取得するSELECT文を実行した後で、「SELECT PLAN_TABLE_OUTPUT FROM TABLE(DBMS_XPLAN.DISPLAY())」文を実行すればよい。