« 実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 Day 24 | トップページ | 実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 おまけ#1 »

2019年12月25日 (水)

実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 Day 25

実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 Day 25のエントリーです.
そして, ついに Advent Calendar 2019 全部俺 完走でございます. T_T 感涙w

Day 24 のつづきから.



CONNECT BY NO FILTERING WITH START-WITHとPredicate Information の 1 - access("MGR"=PRIOR "EMPNO")という部分から, Oracle Databaseの方言であると気づけた方は正解です.

CONNECT BY と PRIOR を利用した階層問合です. この手の問合ができなかったRDBMSではアンチパターンとされていましたが, Oracle Databasedでは..思い出せない, Oracle 7のころにはすでに存在していた構文です.

以下のようなSQL文をイメージできたら正解だと思います.

select
empno
,ename
,job
,mgr
,level
from
emp
start with
mgr is null
connect by
prior empno = mgr;


Connect-by-no-filtering-with-startwith





では, Advent Calendar最後なので, 本題と、あわせて解説もしてしまいましょう!

実行計画は以下のような感じになります.
Union-all-recursive-with-depth-first-rec


最後のお題は, 他のRDBMSでも利用できるようになったものが多い, 再帰問合です. 階層問合と同じことも行えます.
ただし、実行計画を見ていただくとわかりますが, 階層問合より再帰問合のほうが実行計画で行う必要のある操作が多いことに気づくはずです. この例の再帰問合では, EMP表に加え, IX_EMP索引を INDEX FULL SCANしたうえで, EMP表を統べてアクセスしているように見えます. TABLE ACCESS FULLでもよいとは思いますが, オプティマイザのミスかもしれませんね.(詳細まで調べてないですが)
つまり, 階層問合のTABLE ACCESS FULLが一度だけの実行計画と比較しても明らかに操作が多いことがわかります. この結果から, 階層問合と同じ結果を再帰問合で得るより, 方言ではありますが, 階層問合を利用したほうがコストは低いと考えることができます. 標準的な再帰問合を利用するか方言の階層問合を利用するかはその時の判断にはなりますが, これらの特徴を理解したうで, どちらを利用するか判断したようが良いと, 私は考えています.

with
employees (
empno
, ename
, job
, mgr
, lvl
) as
(
select
empno
, ename
, job
, mgr
, 1 lvl
from
emp
where
mgr is null
union all
select
e1.empno
, e1.ename
, e1.job
, e1.mgr
, e2.lvl + 1
from
emp e1
inner join employees e2
on
e2.empno = e1.mgr
)
search depth first by
mgr
, empno
set order#
select
empno
, ename
, job
, mgr
, lvl
from
employees
order by
order#;

そういえば, 昔, 階層問合と再帰問合ネタを書いてましたw
階層問合せか、再帰問合せか、それが問題だ
階層問合せか、再帰問合せか、それが問題だ #2
階層問合せか、再帰問合せか、それが問題だ #3 おまけ

--------
来年も JPOUG をよろしくお願いいたします。

では、皆様、メリークリスマス、そして、良いお年をお迎えください。



previously on Mac De Oracle
・実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 - Day 1 / TABLE FULL SCAN
・実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 - Day 2 / INDEX UNIQUE SCAN
・実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 - Day 3 / INDEX RANGE SCAN, Index Only Scan
・実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 - Day 4 / INDEX RANGE SCAN
・実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 - Day 5 / INDEX RANGE SCAN, INLIST ITERATOR
・実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 - Day 6 / INDEX FAST SCAN, Index Only Scan
・実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 - Day 7 / INDEX FULL SCAN、Index Only Scan
・実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 - Day 8 / INDEX SKIP SCAN
・実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 - Day 9 / TABLE ACCESS INMEMORY FULL
・実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 - Day 10 / NESTED LOOP JOIN
・実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 - Day 11 / MERGE JOIN
・実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 - Day 12 / HASH JOIN
・実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 - Day 13 / HASH JOIN OUTER
・実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 - Day 14 / HASH JOIN FULL OUTER
・実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 - Day 15 / PX, TABLE ACCESS FULL
・実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 - Day 16 / CONCATENATION
・実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 - Day 17 / SORT UNIQUE, UNION-ALL = UNION
・実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 - Day 18 / UNION-ALL
・実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 - Day 19 / INTERSECTION
・実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 - Day 20 / MINUS
・実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 - Day 21 / WINDOW NOSORT STOPKEY
・実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 - Day 22 / COUNT STOPKEY
・実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 - Day 23 / HASH JOIN - LEFT-DEEP JOIN vs RIGHT-DEEP JOIN
・実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 - Day 24 / CONNECT BY NO FILTERING WITH START-WITH

|

コメント

コメントを書く