Oracle 実行計画の見方のサンプル

Oracleの実行計画の見方のサンプルです。

確認環境
・Oracle Express Edition 11g Release 2
・SQL Developer 19.1.0.094

目次

サンプル 前提
  フルスキャン
  INDEX RANGE SCAN
  Bツリーインデックスのイメージ
  INDEX UNIQUE SCAN
  NESTED LOOPS
  HASH JOIN

前提

以下のテーブルがあるとします。件数は10万件です。

CREATE TABLE SYAINDB(
	ID NUMBER(6,0),
	NAME VARCHAR2(20) not null,
	PRIMARY KEY ("ID")
);
SYAINDBテーブル
ID NAME
1 GAKRL
2 GPVYF
  ・・・

Oracle SQL Developerで実行計画を取得します。
Oracle SQL Developerで実行計画を確認する方法

 

フルスキャン

select * from SYAINDB where name = 'ODTGN'

インデックスがない項目の値を指定して検索します。

select * from table(dbms_xplan.display_cursor(sql_id=>'59kfzqw3mpmds', format=>'ALLSTATS LAST'));

上記SQLで実行計画を取得します。

11行目は、「TABLE ACCESS FULL」で全件検索しています。where句にインデックスがない項目を指定したためです。

 

INDEX RANGE SCAN

CREATE INDEX SYAINDB_IDX1
On SYAINDB (NAME);

テーブルの項目のNameにインデックスを作成します。

select * from SYAINDB where name = 'ODTGN'

where句でインデックスを設定した列を指定して検索します。

select * from table(dbms_xplan.display_cursor(sql_id=>'ggwmpdz49vvj2', format=>'ALLSTATS LAST'));

上記SQLで実行計画を取得します。

12行目は、18行目の("NAME"='DXSRM')で「INDEX RANGE SCAN」しています。
NAME列の値は一意ではないので範囲(RANGE SCAN)になりました。
11行目は、取得したROWIDでSYAINDBにアクセスしています。

 

Bツリーインデックスのイメージ

以下は、Bツリーインデックス(B+Tree)のイメージです。

3を探す場合、一番上の5より小さいので左下に行き、2より大きいので右下に行き3を見つけます。
ポイントは、全件検索しなくて良くなることです。

 

INDEX UNIQUE SCAN

select * from SYAINDB where id = '34225'

where句で主キーの値を指定して検索します。

select * from table(dbms_xplan.display_cursor(sql_id=>'2fyq9n9jtdkxu', format=>'ALLSTATS LAST'));

上記SQLで実行計画を取得します。

12行目は、18行目の("ID"='34225')の「INDEX UNIQUE SCAN」しています。
ID列の値は主キーで重複がないため一意(UNIQUE SCAN)になりました。
11行目は、取得したROWIDでSYAINDBにアクセスしています。

NESTED LOOPS

select 
  s1.id,
  s2.name
from SYAINDB s1 
  inner join SYAINDB2 s2
on 
  s1.id = s2.id;

テーブルをinner joinで結合します。SYAINDB2はSYAINDBと同じ構造で100件データがあります。

select * from table(dbms_xplan.display_cursor(sql_id=>'86zcwn9jq7wm0', format=>'ALLSTATS LAST'));

上記SQLで実行計画を取得します。

13行目は、「TABLE ACCESS FULL」で全件検索しています。
14行目は、20行目の("S1"."ID"="S2"."ID")の「INDEX UNIQUE SCAN」しています。
12行目は、13,14行目で取得したレコードをNESTED LOOPSで結合しています。

HASH JOIN

select 
  s1.id,
  s2.name
from SYAINDB s1 
  inner join SYAINDB2 s2
on 
  s1.name = s2.name;

テーブルをinner joinで結合します。

select * from table(dbms_xplan.display_cursor(sql_id=>'5v469v2ag04d3', format=>'ALLSTATS LAST'));

上記SQLで実行計画を取得します。

13行目は、「TABLE ACCESS FULL」SYAINDB2を全件検索しています。
14行目は、「TABLE ACCESS FULL」SYAINDBを全件検索しています。
12行目は、20行目の("S1"."NAME"="S2"."NAME")で「HASH JOIN」しています。

関連の記事

Oracle SQL インデックス作成/使用のサンプル

△上に戻る