SAK 図書館
SQL チューニング編2 - SQL 実行計画解析、EXPLAIN、表走査、索引走査
Oracle 固有の部分があるかもしれません。SQL-Server、MDB では注意のこと。
■実行計画解析
・SQL の実行計画がどのようになっているか調査することができる。
まず、調査スキーマに plan_table を作成する。
これは、調査スキーマで一度だけ実行すればよい。
(データベース最適化、データベースチューニング、テーブル最適化)
@j:\orawin95\rdbms80\admin\utlxplan.sql
・utlxplan.sql では、次の plan_table が作成される。
create table plan_table (
statement_id varchar2(30),
timestamp date,
remarks varchar2(80),
operation varchar2(30),
options varchar2(30),
object_node varchar2(128),
object_owner varchar2(30),
object_name varchar2(30),
object_instance numeric,
object_type varchar2(30),
optimizer varchar2(255),
search_columns number,
id numeric,
parent_id numeric,
position numeric,
cost numeric,
cardinality numeric,
bytes numeric,
other_tag varchar2(255),
partition_start varchar2(255),
partition_stop varchar2(255),
partition_id numeric,
other long
);
・plan_table を削除するには、次のようにする。
drop table plan_table;
・実行計画を採取するには、次のように目的の SQL 文を発行する。
truncate table plan_table;
explain plan for
select * from sak.受注m where 受注番号 like '00%' order by 受注番号
;
・実行計画を問い合わせ表示するには、次のようにする。
select operation || ' options= ' || options || ' object= ' || object_name
|| ' position= ' || position || ' cost= ' || cost from plan_table;
・結果は、次のように表示される。
【SELECT STATEMENT options= object= position= cost=
【TABLE ACCESS options= BY INDEX ROWID object= 受注M position= 1 cost=
【INDEX options= RANGE SCAN object= SYS_C00866 position= 1 cost=
・例えば、次の SQL を発行したとする。
where が中間一致になっているため、
INDEX options= FULL SCAN
となる。
これでは索引の意味がない。
truncate table plan_table;
explain plan for
select * from sak.受注m where 受注番号 like '_0%' order by 受注番号
;
select operation || ' options= ' || options || ' object= ' || object_name
|| ' position= ' || position || ' cost= ' || cost from plan_table;
【SELECT STATEMENT options= object= position= cost=
【TABLE ACCESS options= BY INDEX ROWID object= 受注M position= 1 cost=
【INDEX options= FULL SCAN object= SYS_C00866 position= 1 cost=
・例えば、次の SQL を発行したとする。
受注sv には索引がないため、
TABLE ACCESS options= FULL
になる。
受注m に対して、同じ SQL を発行したときは、索引があるので、
TABLE ACCESS options= BY INDEX ROWID
INDEX options= RANGE SCAN
となっていた。
truncate table plan_table;
explain plan for
select * from sak.受注sv where 受注番号 like '0%' order by 受注番号
;
select operation || ' options= ' || options || ' object= ' || object_name
|| ' position= ' || position || ' cost= ' || cost from plan_table;
【SELECT STATEMENT options= object= position= cost=
【SORT options= ORDER BY object= position= 1 cost=
【TABLE ACCESS options= FULL object= 受注SV position= 1 cost=
・例えば、次の SQL を発行したとする。
where が索引の一致になっているため、
INDEX options= UNIQUE SCAN
となる。
truncate table plan_table;
explain plan for
select * from sak.受注m where 受注番号 = '000001-001'
;
select operation || ' options= ' || options || ' object= ' || object_name
|| ' position= ' || position || ' cost= ' || cost from plan_table;
【SELECT STATEMENT options= object= position= cost=
【TABLE ACCESS options= BY INDEX ROWID object= 受注M position= 1 cost=
【INDEX options= UNIQUE SCAN object= SYS_C00866 position= 1 cost=
・例えば、次の SQL を発行したとする。
where で索引を加工してしまっているので、
TABLE ACCESS options= FULL
になり、索引がまったく使用されていない。
truncate table plan_table;
explain plan for
select * from sak.受注m where substr(受注番号, 1, 6) = '000001' order by 受注番号
;
select operation || ' options= ' || options || ' object= ' || object_name
|| ' position= ' || position || ' cost= ' || cost from plan_table;
【SELECT STATEMENT options= object= position= cost=
【TABLE ACCESS options= FULL object= 受注M position= 1 cost=
・上と同じ結果を得るのであれば、次の SQL を発行した方が良い。
where で like の前方一致を索引に対して使用しているので、
INDEX options= RANGE SCAN
となる。
truncate table plan_table;
explain plan for
select * from sak.受注m where 受注番号 like '000001%' order by 受注番号
;
select operation || ' options= ' || options || ' object= ' || object_name
|| ' position= ' || position || ' cost= ' || cost from plan_table;
【SELECT STATEMENT options= object= position= cost=
【TABLE ACCESS options= BY INDEX ROWID object= 受注M position= 1 cost=
【INDEX options= RANGE SCAN object= SYS_C00866 position= 1 cost=
・not や is null の where 句も全表走査になりやすい。
not is null は > '' で代替え可能な場合もある。
少なくとも RANGE SCAN になるように工夫した方が良い。
■options の種類
・TABLE ACCESS options= BY USER ROWID
- rowid により走査している
・TABLE ACCESS options= FULL
- 全表走査している
・INDEX options= UNIQUE SCAN
- 索引に対して等価検索している
・INDEX options= RANGE SCAN
- 索引に対して範囲検索している
■SQL チューニング編資料
■SQL 基礎実地編資料
■SQL 基礎編資料
■Oracle PL/SQL 編資料
■PostgreSQL 編、JAVA Servlet、JSP 編資料
■MySQL 編資料