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")
);
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」しています。
関連の記事