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

| | | コメント (0)

2019年12月24日 (火)

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

実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 Day 24のエントリーです.

Day 23 のつづきから.



2つのHASH JOINのなにが違うのか. 実行計画の見た目は異なりますが, SQL文はどちらも同じです. (ただし, 2つめの実行計画はヒントを利用して強制した実行計画です.)
どちらの実行計画も3表をINNER JOINしています.

違いは結合順序.

一つ目は一般的なバッチ系処理でよく見かけますが, 二つ目はDWH系で見かけることが多いのではないでしょうか? 
バッチ系でも必要があれば同様の最適化は行われますが ;)

一つ目は小さいと見積もられているTAB3表をビルド表にして、次に小さいと見積もられているTAB311を結合、その結合結果をビルド表にしてTAB31と結合しています.

二つ目はヒントで無理やり変更している影響で実行計画の見積もり行数やサイズに惑わされてしまいますが, そこは気にしないでください. m(_ _)m
ビルド表が, TAB311とTAB31になっていることに気づければ100点です.
ハッシュ結合のビルド表には結果セットの小さいものが選ばれます.
つまり, TAB3表が実はDWHでいうFACT表になっているようなケースで, 結合するディメンジョン表の表が小さい表となる状況(スタースキーマ)をイメージできればOKだと思います.

SQL文は同じでもハッシュ結合するビルド表を適宜入れ替えています.
DWH系では, ファクト表が巨大であるケースが多く一つ目の実行計画場合, TAB3と結合した結果巨大なビルド表を持ち回ることになりハッシュ結合の特性上どうしても不利になります.
それを避けるため, ファクト表より小さいディメンジョン表が常にビルド表になるような実行計画が, 二つ目の実行計画です.

以下、津島さんが紹介している left-deep joinとright-deep joinも参考するとよいと思います.
津島博士のパフォーマンス講座 第46回 パーティション・プルーニングとハッシュ結合について
https://www.oracle.com/technetwork/jp/database/articles/tsushima/tsushima-hakushi-46-2547814-ja.html


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

select
*
from
tab3
inner join tab31
on
tab3.item_code = tab31.item_code
inner join tab311
on
tab3.unique_id = tab311.unique_id;

RIGHT-DEEP joinの実行計画へ強制変更させたヒントは以下のとおり. 二つ目の実行計画はこのヒントでオプティマイザの意思に反しw むりやり作り出した実行計画です.

select
/*+
swap_join_inputs(tab31)
swap_join_inputs(tab311)
*/
*
from
tab3
inner join tab31
on
tab3.item_code = tab31.item_code
inner join tab311
on
tab3.unique_id = tab311.unique_id;


Leftdeep-join
Rightdeep-join




では、本題.


この実行計画という名のレントゲン写真から, どのようなSQL文をイメージしますか? また, どのような特徴をもっていると思いますか?

CONNECT BY NO FILTERING WITH START-WITHはむかしからあるOracle Databaseの方言で, 最近は他のRDBMSでも似たような構文が使えるようになりましたよね...なんとなく, 最終日のヒントを書いてしまったような気がしないでもない.
Connect-by-no-filtering-with-startwith


--------
全部俺 Advent Calendarももう少し。がんばれ、俺w


Day 25 へつづく



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

| | | コメント (0)

2019年12月23日 (月)

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

実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 Day 23のエントリーです.

Day 22 のつづきから.



COUNT STOPKEY前日のWINDOW NOSORT STOPKEYに似てはいます. もうお気づきですよね? 方言のほうです.

STOPKEYなので, 行数をカウントしています. Predicate Informationをみると答えもでています. 1 - filter(ROWNUM<=3) が構文のヒントですよね.

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

select 
*
from
tab3
where
rownum <= 3;

Count_stopkey




では、本題.

今回は, なんと, 2のレントゲン写真.

この実行計画という名のレントゲン写真から, どのようなSQL文をイメージしますか? また, どのような特徴をもっていると思いますか?

どちらもDay 12に紹介したHASH JOINですが, 何かがちがいますよね? どのような状況なのでしょうか?
Leftdeep-join
Rightdeep-join


--------
ねむけをこらえつつw


Day 24 へつづく



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

| | | コメント (0)

2019年12月22日 (日)

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

実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 Day 22のエントリーです.

Day 21 のつづきから.



WINDOW NOSORT STOPKEY STOPKEY とでて行数をカウントしてるってイメージが浮かんだらほぼ正解で, 方言をつかうか, SQL:2008 な違いになってきます. とは言っても多少癖が違ったりしますが.

比較的あたらしいと昨日書いていたのがヒントではあるのですが, WINDOW というところと, Predicate Information に 内部的には、ROW_NUMBER() OVER() とWINDOWS関数を利用しているところに気がつけば, SQL:2008 側の構文であるこに気づけるはずです.

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

select 
*
from
tab3
fetch first 3 rows only;

Window_nosort_stopkey




では、本題.

この実行計画という名のレントゲン写真から, どのようなSQL文をイメージしますか? また, どのような特徴をもっていると思いますか?

これ, すでにヒント出ちゃってるので簡単ですよね.
Count_stopkey

--------
Advent Calendarもあと少し.

Day 23 へつづく


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

| | | コメント (0)

2019年12月21日 (土)

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

実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 Day 21のエントリーです.
Day 20 のつづきから.



UNION, UNION ALLやINTERSECTIONににていますが, Operationがちがいますよね. UNION/INTERSCTIONときたら残るは..... MINUS そのまんまですw
Predicate InformationやOperetion部分から, UNIONやUNION ALLで使われた述語と同じなであることが確認できる2つのSELECT文が見えてきます. あとはそれらの結果セットをどうするかという違いですよね.

Minus_image

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

select 
*
from
tab311
where
unique_id between 1 and 100
minus
select
*
from
tab311
where
sub_item_code in ('0000000100','0100000000');


Minus


では、本題.

この実行計画という名のレントゲン写真から, どのようなSQL文をイメージしますか? また, どのような特徴をもっていると思いますか?

おお, これは! 比較的あたらしい部類ですね. Oracle Databaseの実行計画では.

Window_nosort_stopkey

 


--------
ながいーーーーーい、ほぼ一ヶ月を抜けた....ほっとして熱でないといいけどw

Day 22 へつづく



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

| | | コメント (0)

2019年12月20日 (金)

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

実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 Day 20のエントリーです.

Day 19 のつづきから.



UNIONやUNION ALLににていますが, Operationがちがいますよね. しかもわかりやすいです. INTERSECTION そのまんまです.

Predicate InformationやOperetion部分から, UNIONやUNION ALLで使った述語と同じで, 2つのSELECT文が見えてきます. あとはそれらの結果セットをどうするかという違いです.
Intersect_img


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

select 
*
from
tab311
where
unique_id between 1 and 100
intersect
select
*
from
tab311
where
sub_item_code in ('0000000100','0100000000');

Intersection




では、本題.


この実行計画という名のレントゲン写真から, どのようなSQL文をイメージしますか? また, どのような特徴をもっていると思いますか?

MINUS...そこに気づけば簡単ですよね.
Minus


--------
お通しがカニっていいよなー(謎

Day 21 へつづく



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

| | | コメント (0)

2019年12月19日 (木)

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

実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 Day 19のエントリーです.

Day 18 のつづきから.



Day 17のレントゲン写真とDay 18のレントゲン写真を比較するとすぐに気づけるとおもいます.
Day 17 - UNION
Sort-unique_union_all

Day 18 - ? Similar to UNION
Union-all


SORT UNIQUEというOperationがないだけです. :) となると答えは簡単.

Id = 1 がUNION-ALLというOperationから, UNION ALL という構文なのは明らかです.

Id = 3,2 そして,  Predicate Informationの ”3 - access("UNIQUE_ID">=1 AND "UNIQUE_ID"<=100)” から 一つ目のSELECT文は, 索引範囲検索で表をアクセス.

Id = 6.5.4 そして,  Predicate Informationの "6 - access("SUB_ITEM_CODE"='0000000100' OR "SUB_ITEM_CODE"='0100000000')" から 二つ目のSELECT文は, INLIST ITERATORで索引範囲検索で表を繰り返しアクセス.

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

select 
*
from
tab311
where
unique_id between 1 and 100
union all
select
*
from
tab311
where
sub_item_code in ('0000000100','0100000000');

UNION ALLも複数のSELECT文を実行するより1つのSQL文にしたほうが効率が良いのであれば、手術という名の書き換えしかないのは, UINONの場合と同じです. Index Only Scanが使える場合はUNION ALLのままにしておくなんてケースはあると思いますが, そもそも索引の追加はしてほしくないという, 大人の事情があるったり, なかったり.

大人って大変なんです. むーりーなものはむーりーと言われることはあって, それでも, こちらは, Index Only Scan or Die? って突きつけないといけないこともあるのでw Vector Transformな案件はそんなアトモスフィアだった, 遠ーい目w

そして, 「私, 失敗しないので!」 的なw 言葉を残しつつサクッと帰宅しちゃいましょ! (またかよw
フリーランスにはメロンおじさんが必要だなw





では、本題.


この実行計画という名のレントゲン写真から, どのようなSQL文をイメージしますか? また, どのような特徴をもっていると思いますか?

INTERSECTION...そこに気づけば簡単ですよね.
Intersection


--------


Day 20 へつづく



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

| | | コメント (0)

2019年12月18日 (水)

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

実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 Day 18のエントリーです.

Day 17 のつづきから.



Day 17のレントゲン写真を読み解いてみましょう.

Id = 2 の UNION-ALLというOperationから, UNION ALL という構文であることが読み取れます.

Id = 1 から UNION ALL であるが, SORT UNIQUE されている. つまり, UNION ALL した後に、各SELECT文から返された行から重複行を排除していることが読み取, 実際には, UNION ALL ではなく UNION であること希読み取れればあとは簡単.

Id = 4,3 そして,  Predicate Informationの ”4 - access("UNIQUE_ID">=1 AND "UNIQUE_ID"<=100)” から 一つ目のSELECT文は, 索引範囲検索で表をアクセス.

Id = 7, 6, 5 そして,  Predicate Informationの "7 - access("SUB_ITEM_CODE"='0000000100' OR "SUB_ITEM_CODE"='0100000000')" から 二つ目のSELECT文は, INLIST ITERATORで索引範囲検索で表を繰り返しアクセス.

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

select 
*
from
tab311
where
unique_id between 1 and 100
union
select
*
from
tab311
where
sub_item_code in ('0000000100','0100000000');

INDEX RANGE SCANで表をアクセスしているので、この例では無理ですが、可能ならCovering IndexでIndex Only Scanの持ち込む治療も行える可能性はあります. それはあくまで治療の必要のある大人の事情がある場合ですがw

なお、Day 16 の CONCATENATION という, 最適化と同じ意味ではあるのですが、UNION のOperationと区別されている点に注目してください.

重要. 治療が必要な場合, NO_EXPANDヒントという注射で治療するか, SQL書き換えという手術が必要なのか判断できるポイントになるからです!!!

重要. 治療が必要な場合, NO_EXPANDヒントという注射で治療するか, SQL書き換えという手術が必要なのか判断できるポイントになるからです!!!

たいせつなので二度書きましたw (ひさびさw


UNION の場合, オプティマイザは, Day 16のようなSQL文へ内部的に書き換える最適化は行いません. (将来はどうなるかしりませんが) なので, UNION で索引使ってくれるかと思ってたが、使ってくれない. 無理に使わせても全表走査のほうが効率がよいのなら, Day 16のような構文に書き換える手術をおこない, 2回の全表走査から1回の全表走査で済むようにしちゃいましょ.

そして, 「私, 失敗しないので!」 的なw 言葉を残しつつサクッと帰宅しちゃいましょ!

Sort-unique_union_all




では、本題.


この実行計画という名のレントゲン写真から, どのようなSQL文をイメージしますか? また, どのような特徴をもっていると思いますか?

UNON系構文ぽい...簡単です. ちがいに気づけば.
Union-all


--------
やらないことを決めないと時間がないw

そういえば, Doctor X で, やらないことを事前に伝えてるのに気づく.


Day 18 へつづく
そして、JPOUG Advent Calendar 2019も Day 18 へつづく



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 / UNION

| | | コメント (0)

2019年12月17日 (火)

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

実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 Day 17のエントリーです.
また、
JPOUG Advent Calendar 2019 Day 17のエントリーとのクロスポストとなっています.


Day 16 のつづきから.
そして、JPOUG Advent Calendar 2019 Day 16のエントリーは, 「 Oracle Advanced Queuing(AQ)使ってみませんか? / kjmtgm さん」でした



昨日の実行計画の特徴は, CONCATENATIONこのオペレーションを見たら, あれだ! と気が付けるように日々精進しておくと, 一目置かれるような存在に, なれるとか, なれないとかw (保証はしませんw

このオペレーションは、SQLトランスフォームの一つです. 表を検索する際に、同一表の異なる列が OR 条件で利用されており、単一索引利用するより、OR条件のそれぞれの列で個別の索引を利用させることで複数の索引を同時に利用させるようにUNIONを利用し個別のSELECT文に分割統合します. (内部でどう書き換えているかは後半でお見せします)


実際のSQL文は、以下のようなSQL文をイメージできたら正解だと思います. USE_CONCATヒントで強制することもありますが, もちろんオプティマイザの判断で行うこともあります. オプティマイザの判断が誤っている場合には, NO_EXPANDヒントというヒントで抑止することも可能です.

select 
*
from
tab311
where
unique_id= 1
or sub_item_code = '0001000000';

select 
/*+
use_concat
*/
*
from
tab311
where
unique_id= 1
or sub_item_code = '0001000000';


SQLヒントや, オプティマイザに任せず, 書き換えるという昔のスタイルだと, 上記SQL文を以下のように書き換えると同じ意味になります ;) オプティマイザは偉い. まちがいもするけど. それは人も同じw 失敗を肥やしにして訂正するのも, 最近のオプティマイザの賢いところ. ですが, それでもだめなら, 人の手でw

このような書き換えが行われる, もしくは有利な場面は、ORで利用されている列がそれぞれ個別の索引を持ちそれぞれの条件で索引アクセスのコストが低くなる一意検索だったり, 比較的狭い範囲の索引範囲検索が有効な場合です. 統計情報と実態の乖離が大きい場合にはオプティマイザが誤って選択してしまうケースもあります. このままで行くか, 治療するかの見極めが必要になることも意外に多いタイプですね.
以下のような書き換えをした場合, 最悪のケースは, どちらのSELECT文でも全表走査してしまうケースで, どちらも索引を利用しないのが正しいのであれば, 2つのSELECT文で全表走査を2回行わせるより, 書き換える前のSQL文で1度だけ全表走査させたほうがはるかに効率できてきすw (セグメントサイズにもよりますが)

ポイントは, 2つのSQL文にしてUNIONしたほうが無駄ないのかどうかを考える! ということです.

select 
*
from
tab311
where
unique_id = 1
union
select
*
from
tab311
where
sub_item_code = '0001000000';

あ、しまった....あ...いいや、構文おなじだけだしw


Concatenation





では、本題.


この実行計画という名のレントゲン写真から, どのようなSQL文をイメージしますか? また, どのような特徴をもっていると思いますか?

少しだけネタバレしましたが今回も特徴のあるわかりやすいOperationがでてますよね. 見た目は違いますが同じですが, ヒントw
Sort-unique_union_all


--------
外資系って, 31まで仕事なのな, というのに気づいて 2 年目ですw 私個人の営業は 30までですがw


Day 18 へつづく
そして、JPOUG Advent Calendar 2019も Day 18 へつづく



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

| | | コメント (0)

2019年12月16日 (月)

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

実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 Day 16のエントリーです.

Day 15 のつづきから.



Id = 4のOperationはTABLE ACCESS FULLですが, Id = 1から Id = 3に特徴があります.
PX ときたら! そう, Parallel Executionですよね.

PX BLOCK ITERATORで非パーティションをパラレルにアクセスしていいます.

Note部分に, Degree of Parallelism is 4 because of hint なんてあるので、HINTを使ってパラレル化していることも読み取れます. HINTなしでもTABLE等に並列度が設定されている場合には設定されている並列度でパラレル化されます. 意図せずパラレル実行されている場合には、NO_PARALLELヒントで抑止したり, そもそも表や索引に並列度設定するつもりじゃなかったという場合には、表や索引の並列度をNOPARALLELにしましょう. 昔、そんな事故がありましたw

この場合, HINTが利用されているのはあきらかなので, 以下のようなSQL文をイメージできたら正解でしょうね.

select 
/*+
parallel(4)
*/
*
from
tab3;

ちなみに, このテーブルの並列度は, 以下の通りに設定されておりました.

SCOTT> select table_name,degree from user_tables where table_name='TAB3';

TABLE_NAME DEGREE
------------------------------ ---------------
TAB3 1


Px





では、本題.


この実行計画という名のレントゲン写真から, どのようなSQL文をイメージしますか? また, どのような特徴をもっていると思いますか?

CONCATENATIONなのはわかると思いますが, わかりやすいOperationがでてますよね. それが, ポイント.
Concatenation


--------
3ヶ月がはえーよw


Day 17 へつづく



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

| | | コメント (0)

2019年12月15日 (日)

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

実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 Day 15のエントリーです.

Day 14 のつづきから.



この実行計画はわかりやすいですよね, 読んだまんまです. HASH JOIN FULL OUTER

もうそのまま, SQLに書いちゃえばいいですよね. 結合条件は, Predicate Information に Id=2 の部分は 2 - access("TAB3"."UNIQUE_ID"="TAB311"."UNIQUE_ID") としてリストされています.

以下のようなSQL文をイメージできたら正解でしょうね.

select 
*
from
tab3
full outer join tab311
on
tab3.unique_id = tab311.unique_id;


Fullouterj





では、本題.


この実行計画という名のレントゲン写真から, どのようなSQL文をイメージしますか? また, どのような特徴をもっていると思いますか?

TABLE FULL SCANなのはわかると思いますが, 特殊なOperationがでてますよね. それが, ポイント.
Px

--------
一日中缶詰で, チューナーっぽくない物書き、俺一番萌えないやつじゃん, それw


Day 16 へつづく



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

| | | コメント (0)

2019年12月14日 (土)

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

実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 Day 14のエントリーです.

Day 13 のつづきから.



眠気と戦いながらw 書いているので, タイポ多目とか. ケンブリッジ関数通してないのに文字の順序入れ替わっているとかありましたら, ここまでご連絡くださいませ.(どこだよーw

というジャブはこれぐらいにしておいて,

この実行計画も adaptive plan となっているので, 実際には NESTED LOOPS で実行されている可能性のある HASH JOIN ですよね? 

HASH JOINのナカーマではありますが, HASH JOIN OUTER という部分で気づくかもしれませんが, OUTER という部分で外部結合であることがわかります.
また、Predicate Information には結合条件にOracleの方言に書き換えられた結合条件に気づけるとおもいましす. Id=1に対応するPredicate Informationの1 - access("TAB3"."UNIQUE_ID"="TAB311"."UNIQUE_ID"(+))がそれですね.

Predicate Informationも含め, 以下のようなSQL文をイメージできたら正解だとおもいます.

select 
*
from
tab3
left join tab311
on
tab3.unique_id = tab311.unique_id
where
tab3.unique_id between 1 and 100;

Hjouter





では, 本題.


この実行計画という名のレントゲン写真から, どのようなSQL文をイメージしますか? また, どのような特徴をもっていると思いますか?

Fullouterj

今日は結合は結合でもあまり使わないですね. 業務系で使いどころがあまりなく....w....何年か前にExadataへの移行案件で, 出会った結構痺れるチューニング案件を思い出す, この結合.

--------
今日は寝落ちしてないけど、なんでこんなに忙しいんだw


Day 15 へつづく



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

| | | コメント (0)

2019年12月13日 (金)

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

実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 Day 13のエントリーです.

Day 12 のつづきから.



さてさて、Advent Calendarも半分ぐらい. あともうひと頑張りw

HASH JOINとは出ていても、TABLE ACCESS FULL SCANとはかぎらず、INDEX RANGE SCANとTABLE ACCESS BY INDEX ROWID BATCHEDとの組み合わせも意外に見かけます. このようなケースでは, 全表走査や高速索引走査(INDEX FAST FULL SCAN)でIndex Only Scan狙いの治療も考えられますが, それはおいといて.

ハッシュ結合で最初に見るべきポイントは、結合順. NESTED LOOPSも同じですが、結果セットの小さい方がビルド表(外部表, NESTED LOOPSの駆動表)になっているかを確認しておきましょう. もし違うのであれば、統計情報を最新化(実態との乖離が大きければ)、そうでなければヒント等で実行計画を管理する方向にするか. オプティマイザがなんとなく理解してくれるまでまつ.
ということになります.

また, Note部分に - this is an adaptive plan が現れています. これは HASH JOIN かもしれないし、 NESTED LOOPSかもしれない 実行計画であることをしめしています. 実際にヒットする行数によってどちらになるかがきまります. この例ではSQL*Plusのautotraceを利用しているため, 静的な統計情報を基にした, 見積もりなので実際にはどちらのプランで動作したのかはわかりません.
動作時の実行計画を確認するには, Actural Planを確認する必要があります.

Enterprise Editionでオプションが利用できる状況であれば、SQLモニター, そうでなければ、DBMS_XPLAN.DISPLAY_CURSOR()を利用してActual Planを確認できます.

dbms_sqltune.report_sql_monitorを利用する. (typeパラメタータを 'text' にすることでhtmlではなく、textでレポートを出力することもできます)
「高度なSQL実行計画の取得」を実践する (2/3)

/*+ gather_plan_statistics */ やalter session set statistics_level=all;とDBMS_XPLAN.DISPLAY_CURSOR()を利用したActual Planの確認
DBMS_XPLAN.DISPLAY_CURSORの使い方とちょっとした落とし穴


余談がおおくなってしまいましたが, Predicate Informationも含めてイメージすれば, 以下のようなSQL文をイメージできたら正解だとおもいます.

select 
*
from
tab3
inner join tab311
on
tab3.unique_id = tab311.unique_id
where
tab3.unique_id between 1 and 100;


Hj





では、本題.


この実行計画という名のレントゲン写真から, どのようなSQL文をイメージしますか? また, どのような特徴をもっていると思いますか?

Hjouter


HASH JOIN だけどちょいとちがう.
--------
二日連続で寝落ちしてたw


Day 14 へつづく



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

| | | コメント (0)

2019年12月12日 (木)

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

実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 Day 12のエントリーです.

Day 11 のつづきから.



MERGE JOINは最近のOracle Databaseではあまり見かけなくなりましたが, 結合対象データが多い場合かつ, 特定の結合条件ではかならず選択されますよね?

等価結合(=)以外の結合条件で, データ量が多い場合には MERGE JOIN が選ばれます.

Predicate Informationの情報などから次のようなSQL文がメージできれば正解でしょう.

select 
*
from
tab3
inner join tab311
on
tab3.unique_id > tab311.unique_id
where
tab3.unique_id between 1 and 100;

結合条件がMERGE JOINは, ソート処理を伴うこともありソート処理をバイパスできるような索引がない場合はかなり重くなる傾向があります.
今日の本題も予想できちゃいそうですが, ソートをバイパスできそうであれば,MERGE JOINを利用してチューニングしちゃうこともなくはないです. (巨大なデータのソート処理はやはり重いので避けたいところ)

そういえば, HASH JOINもMERGE JOINでも, Temp落ちが激しくて遅かったころは, あえて, NESTED LOOPSに倒すなんてこともありました.... Temp落ちしても早くなってきたので, そこまでするかってのは微妙ではありますが, 最近は.
いずれにしても, 症状と手術の副作用も考えてどうするかってところにはなりますが, 術後のリスクは相手にもしっかり伝えておくことは重要です.

この例の場合も, 大人の事情とSQLの列の利用状況などにもよりもよりますが, Index Only Scanを組み合わせたチューニングすることはあります. アクセスするブロック数がどれだけ減らせるかの検証は必要ですが.

また, 結合条件がない(意図的に行なっている場合も, 結合条件が漏れている場合もあり)場合もMERGE JOINにはなりますが, その場合は, ”MERGE JOIN (CARTESIAN)" というOperationに変わるので区別しやすいとおもいます.
Mj





では、本題.


この実行計画という名のレントゲン写真から, どのようなSQL文をイメージしますか? また, どのような特徴をもっていると思いますか?

Hj

--------
晩御飯たべて、少し横になったら爆睡してて、さっき目覚めたのはナイショw


Day 13 へつづく



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

| | | コメント (0)

2019年12月11日 (水)

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

実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 Day 11のエントリーです.

Day 10 のつづきから.



Day 10 でついに結合の登場. 駆動表となるTAB3のTAB3_PK索引をINDEX UNIQUE SCAN(一意検索)してROWIDを取得(Id=3) 、Id=2でId=3で取得したROWIDを元にTAB3をTABLE ACCESS BY INDEX ROWIDでアクセス後、id=5でPredicate Informationにリストされている結合条件TAB311.UNIQUE_IDでTAB311_PK索引をINDEX RANGE SCAN して複数件のROWIDを取得、最後に、id=4で内部表となっているTAB311から、TABLE ACCESS BY INDEX ROWID BATCHEDで複数のROWIDに対応する複数の行を取得という実行計画になっています.
Nested Loop Joinの基本系といってもよい実行計画になっています。 Id=3,2でアクセスされている表が駆動表(外部表)で、この表は一般的に、内部表(Id=5,4でアクセスされている表)です.
一般的に、駆動表の結果セットは内部表の結果セットより少ないことが、Nested Loop Joinでの性能上重要な意味があります. 統計情報が不正確だったりすると本来内部表であるべき表が駆動表となって思わぬ処理遅延を引き起こします. この実行計画では索引スキャンが妥当か、妥当であること、駆動表が妥当であることなごが性能検証でのポイントになります.

以下のようなSQL文をイメージできたら大体あっていると思います.

select 
*
from
tab3
inner join tab311
on
tab3.unique_id = tab311.unique_id
where
tab3.unique_id = 2;

また、大人の事情とSQLの列の利用状況などにもよりもよりますが、Index Only Scanを組み合わせて、Nested Loop Joinをチューニングすることもあります.
Nlj






では、本題.


この実行計画という名のレントゲン写真から、どのようなSQL文をイメージしますか? また、どのような特徴をもっていると思いますか?

Mj

比較的少量の等価結合では Nested Loop Joinが無難ですが、データ量が多い場合には、これでした. 古いバージョンのOracle Databaseで大量データの結合といえば、この結合という時代もありました. 最近はあまり見かけないのですが、特定の状況ではこれしか使えないという状況もあります. :)

--------
昨日は、ポンギ方面へ久々に行った. むかーし、むかーし、あの辺で仕事してたなぁ〜. 遠い目. そして、10年ぐらい前とは違うビル群...

Day 12 へつづく



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

| | | コメント (0)

2019年12月10日 (火)

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

実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 Day 10のエントリーです.

Day 9 のつづきから.


TABLE ACCESS INMEMORY FULL となっているので、INMEMORYのTABLE ACCESS FULL という状況なのはすぐに読み取れるのではないでしょうか?
また、Predicate Information はリストされていないので、WHERE句がないという点にもきづくと思います. そう Day 11)のSQL文と同じ.
INMEMORYはEnterprise Editionの機能(SEに降りてくる機能もありますが、今のところ)なので、そのあたりも想像できます. (SQL文自体には関係ないわけで)

select * from tab3;

INMEMORYというoperationをみたら、in-memoryが有効化されていると判断すればよいとおもいます. (inmemory_sizeに100MB以上の値がセットされているはずです)
第53回 Oracle Database In-Memoryについて / 津島博士のパフォーマンス講座
in-memory関連の謎パラメータ 18c / Mac De Oracle

 

TABLE ACCESS FULLで物理読み込みがきついのであれば、こんな手も使えなくもないということで....

Table_access-inmemory_full


 


 

では、Day 10の本題

この実行計画という名のレントゲン写真から、どのようなSQL文をイメージしますか? また、どのような特徴をもっていると思いますか?

Nlj

よく見かける実行計画なので、簡単だと思います. :)

 


昨日は、ポンギ方面へ久々に行った. むかーし、むかーし、あの辺で仕事してたなぁ〜. 遠い目. そして、10年ぐらい前とも違うビル群....

 

Day 11 へつづく


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

 

| | | コメント (0)

2019年12月 9日 (月)

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

実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 Day 9のエントリーです.

Day 8 のつづきから.


INDEX SKIP SCANとでていて、Predicate Information に "2 - access("SUB_ITEM_CODE"='0000000001') filter("SUB_ITEM_CODE"='0000000001')" とでている.
そして、TABLE ACCESS BY INDEX ROWID BATCHED あるとなれば、実行計画というレントゲンからSQL文をイメージできるのではないでしょうか?

ヒントで強制されていたり、オプティマイザが判断したかのいずれかのパターンなので以下のようなSQLが浮かぶのではないでしょうか?

select /*+ index_skip(tab31 tab31_pk) */ * from tab31 where sub_item_code='0000000001';
select * from tab31 where sub_item_code='0000000001';

 

Index-skip-scan

ところで、INDEX SKIP SCAN はどのような状況かというと、 
TAB31_PK は複合索引であることが前提になります。複数の列からなるこの索引の列のうち、第2キー以降にPredicate Informationにリストされている sub_item_code列があることになります. たとえば、2列の複合索引があるとして、この実行計画では第2キーのsub_item_code列だけで検索されている. WHERE句で検索条件に利用されているのは sub_item_code列だけということになります.

20191208-03531

INDEX SKIP SCANはINDEX RANGE SCANになるような索引を作成した方が効率がよいことが多いですが、大人の事情縛りのチューニングなどでは、索引の最適化までは行えず、SKIP SCANの効果ができるようであれば、それ以上治療しないという選択もあります.
ただ、可能ならINDEX RANGE SCANになるような物理的な手術を行ったほうがよいケースのほうが圧倒的に多いです. SKIP SCANでもいよいよダメだ、という状況になってから慌てるぐらいなら、バッサリやっちゃったほうがスッキリすると思うんですね. そういうところに限って、夜中や休日に緊急オペで呼び出されるなんてことも意外におおかったです.
最終的には判断患者さんの判断にはなりますが、リスクは伝えておいた方がよいと思います.



さて、本題、Day 9の実行計画というレントゲン写真はこれ!

これは!
とにかく、実行計画をしっかり診てください.

Table_access-inmemory_full

この実行計画という名のレントゲン写真から、どのようなSQL文をイメージしますか? また、どのような特徴をもっていると思いますか?

これは Enterprise Editionの機能ですよね...(ヒント:)

Day 10 へつづく


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

 

| | | コメント (0)

2019年12月 8日 (日)

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

実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 Day 8のエントリーです.

Day 7 のつづきから.


Predicate Informationには何もない、かつ、TAB3_PKという索引を参照しているだけとなれば、Index Only Scanですよね. unique_id列でTAB3_PKという索引があったとして、Day 7のように、INDEX FAST FULL SCANでもない.
索引のキー順に読まむ必要のあるような句があるということ. 索引のキー順に読ままなければならないのは、ORDER BY ですよね?

unique_idという列が索引に含まれていたとして、それ以外の列は参照されていない. そして、ORDER BY unique_id で昇順ソート要求があるなれば、以下のようなSQL文をイメージできていたら正解だと思います.
なお、降順ソートの場合もありますが、その場合は INDEX FULL SCAN DESCENDINGとなります.

select unique_id from tab3 order by unique_id;

Index_full_scan



さて、本題、Day 8の実行計画というレントゲン写真はこれ!

ほ、ほう、これは、めずらしい、INDEX SKIP SCAN

Index-skip-scan

この実行計画という名のレントゲン写真から、どのようなSQL文をイメージしますか? また、どのような特徴をもっていると思いますか?

あえて、SKIP SCANで治療したのはかなり少ないのですが、実際に効くケースもあるので、治療の選択肢としてはなくなないですね..索引を変更したりするリスクを避けたいという、大人の事情がある場合、ヒントで SKIP SCANをすることで、試験範囲を限定できたりすることもあります.
ポケットはたくさんあったほうがなにかと便利 :)

Day 9 へつづく


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
・実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 - Day 7 / INDEX FULL SCAN、Index Only Scan

 

| | | コメント (0)

2019年12月 7日 (土)

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

実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 Day 7のエントリーです.

Day 6 のつづきから.



どのようなSQL文かイメージできたでしょうか? その特徴は?

TABLE ACCESS BY INDEX ROWID BATCHEDも無いし、Predicate Information もない. ということはWHERE句はないと読み取れます.

Index Only Scanなのは間違いないですが、INDEX FAST FULL SCAN

このOperationは、高速全索引スキャンは索引順に読む必要のない場合に考慮される実行計画です。例えば、索引の順序づけにしたがって読み出したい場合、order by unique_idのように索引順に読み出したい場合には選択されません.

と、ここまでくれば、 WHERE句なし、ORDER BY句なしで、かつIndex Only Scanなので、SELECTリスト等、参照されている列すべてが索引にふうまれている問い合せと見て良いのではない.

オプティマイザの判断(判断に影響を与えるパラメータがある)で INDEX_FFSヒントを利用しているか、オプティマイザ判断でヒントはないかもしれない場合くらい、以下のようなヒント付きか、ヒントなしの以下SQLをイメージできていれば正解ではないでしょうか.
SCOTT> select /*+ index_ffs(tab3 tab3_pk) */ unique_id from tab3;
SCOTT> select unique_id from tab3;


Index_fast-full-scan-with-index-only-sca


グリーンペペさんのこんなエントリーを思い出しました:)
OraOraOracle Full / Scanを速くしちゃう その6 / ペンネーム:グリーンペペ

yohei-aさんもこんな straceしてたりして
ablog 不器用で落着きのない技術者のメモ / SQLトレースとstrace / yohei-a




さて、本題、Day 7の実行計画というレントゲン写真はこれ!


INDEX FULL SCAN ?

Day 6のOperationに似ていますが、FASTではありません.

Index_full_scan


この実行計画という名のレントゲン写真から、どのようなSQL文をイメージしますか? また、どのような特徴をもっていると思いますか?


いろいろ考えちゃいますね〜。いろいろw

Day 8 へつづく



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 FULL SCAN

| | | コメント (0)

2019年12月 6日 (金)

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

実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 Day 6のエントリーです.

Day 5 のつづきから.



どのようなSQL文かイメージできたでしょうか? その特徴は?

"あれ? INDEX RANGE SCAN + TABLE ACCESS BY INDEX ROWID BATCHED って Day 4 と同じ? と思ったあなた! よーく見てください〜. 違うんですよ〜っ!"

INLIST ITERATORPredicate Information3 - access("UNIQUE_ID"=1 OR "UNIQUE_ID"=10)

3 - access("UNIQUE_ID"=1 OR "UNIQUE_ID"=10) という述語をみれば、 WHERE句に OR 条件があるのは明らかです. :) OR があるのは明らかですが、 実はINLIST ITERATOR というオペレーションは IN句を利用した場合にも発生します。 IN (a, b) って結局、 a or b なので内部的には同じ状況になっています。

この実行計画は、 id=1のINLIST ITERATOR 以下のid=2,3が2回実行されています. 3 - access("UNIQUE_ID"=1 OR "UNIQUE_ID"=10) = UNIQUE_ID IN (1, 10) となり、IN句の中の値の個数分繰り返されている = 2回.

select * from tab311 where unique_id = 1 or unique_id = 10;
select * from tab311 where unique_id in (1, 10);

のいずれかということになります :) INLIST ITERATORで繰り返すのがよいのかはデータ量しだいだと思います。この場合、unique_idが主キーなので2回繰り返しても問題はないと思います。とはいえ、INDEX RANGE SCANだけを2回実行してROWIDをあつめて、TABLE ACCESS BY INDEX ROWID BATCHEDを1回実行したほうがよいのではないかと思わなくもない.
id=1とid=2のOperationを入れ替えれば、INLIST ITERATIONで繰り返すのはINDEX RANGE SCAN(実質、INDEX UNIQUE SCAN を 2回ですが)を2回実行してUNIQUE KEYから2つのROWIDをあつめ、そのあと、TABLE ACCESS BY INDEX ROWID BATCHEDをやったらいいんじゃないかなぁ(細かいこというと)と実行計画をみながら思ったのでした.
Inlist-iterator




さて、本題、Day 6の実行計画というレントゲン写真はこれ!

? TABLE ACCESS BY INDEX ROWID BATCHED がないですね. でもちょっと違う.

INDEX FAST FULL SCANとでています
Index_fast-full-scan-with-index-only-sca

この実行計画という名のレントゲン写真から、どのようなSQL文をイメージしますか? また、どのような特徴をもっていると思いますか?

いろいろ考えちゃいますね〜。いろいろw

Day 7 へつづく



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

| | | コメント (0)

2019年12月 5日 (木)

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

実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 Day 5のエントリーです.

Day 4 のつづきから.



どのようなSQL文かイメージできたでしょうか? その特徴は?

"あれ? INDEX RANGE SCANって Day 3 と同じ? と思ったあなた! よーく見てください〜. 違うんですよ〜っ!"

なにが Day 3 のINDEX RANGE SCANと違うか.... それは Index Only Scanではないというところ.

Predicate Informationは、Day 3とほぼおなじ(リレラル値は異なりますが)、2 - access("UNIQUE_ID">=1 AND "UNIQUE_ID"<=2) となっています. WHERE unique_id BETWEEN 1 AND 2 のようなWHERE句が浮かびますよね?

残るOperationは、Id=1のTABLE ACCESS BY INDEX ROWID BATCHEDです. その他の句を思い浮かべるようなOperationはりません. WHERE句以外で、索引に含まれていない列がどこかに含まれているということに気づけば答えは簡単.

SELECTリストで TAB3_PK索引に含まれていない列が参照されているということになります. 次のようなSQL文をイメージできたら正解だと思います.
SELECTリストは * にしてあるのは、SQL*Plusのautotraceでは、それらを特定するまでの情報はリストされないため、SELECTリストを * にしています. 索引に含まれている列以外を参照させればよいので.

select * from tab3 where unique_id between 1 and 2;
Index_range_scan

ちなみに、TABLE ACCESS BY INDEX ROWID BATCHEDというOperationは、Oracle Database 12cR1 から見られるようになったOperationです.
それまでは、TABLE ACCESS BY INDEX ROWID というOperationだけで、裏では、db file parallel read だったり、db file sequential readだったりしてたのが、実行計画からも判断できるようになって、おお〜っ. と感じたことを思い出した ;)
TABLE ACCESS BY INDEX ROWID BATCHED (Oracle Database 12c R1) ってなに! #3




さて、本題、Day 5の実行計画というレントゲン写真はこれ!

INDEX RANGE SCANN + TABLE ACCESS BY INDEX ROWID BATCHED

Day 4 の実行計画に似てる、でもちょっと違う!

Inlist-iterator

この実行計画という名のレントゲン写真から、どのようなSQL文をイメージしますか? また、どのような特徴をもっていると思いますか?

本気で余裕のない師走w なんだこりゃw というアトモスフィアになってきましたが、皆様、そんな時こそ、体調管理しっかりしましょうね。(自分への注意喚起も込めてw)

Day 6 へつづく



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

| | | コメント (0)

2019年12月 4日 (水)

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

実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 Day 4のエントリーです.

Day 3 のつづきから.



どのようなSQL文かイメージできたでしょうか? その特徴は?

これ私がなんどもネタにしてきた、大好きな、Index Only Scan (Index Only Access という呼び方もあります)でっす:)

Id=1で、INDEX RANGE SCAN となっているので、TAB3_PK索引の特定の範囲、範囲は、Predicate Informationでリストされている 1 - access("UNIQUE_ID">=1 AND "UNIQUE_ID"<=10) なので、 TAB3_PK 索引を UNIQUE_IDが1〜10の範囲で検索していることがわかります.
また、この実行計画のポイントは、Day 2に見られたような、索引から得られる行の位置情報であるROWIDを利用したへのアクセスがないところ.

これの意味するとこは、索引はアクセスするが、表はアクセスしないということを意味しています. つまり、索引だけをアクセスしています.

1 - access("UNIQUE_ID">=1 AND "UNIQUE_ID"<=10) といく述語があるので、WHERE句はあるはずですが、SELECTリストでは、索引列のみが参照されている! = Index Only Scanということになります.

以下のようなSQL文を想像できていれば正解です. :)

select unique_id from tab3 where unique_id between 1 and 10;

Index-range-scan

Index Only Scanのイメージ図は以下のとおり.
20191201-231357

Index Only Scanは表へのアクセスを省略できるのがメリットですが、複数のIndex Only Scanを狙いすぎため結果索引が多くなり、アンチパターンで有名なインデックスショットガンにならないような注意を必要とする点はみなさんご存知なのではないかと思います.
更新系処理の性能要件を満たせている限りガチで使った案件もなくはないですが、それはそれで索引のメンテナンスなども大変になることもあり、用法・用量には注意してくださいね. ;)





ということで、Day 4の実行計画というレントゲン写真はこれ!

INDEX RANGE SCAN

あれ? INDEX RANGE SCANって Day 3 と同じ? と思ったあなた! よーく見てください〜. 違うんですよ〜っ!
Day 3との違いに気づければ、該当するSQL文をイメージするのは簡単なのではないかと思います.
Index_range_scan

この実行計画というなのレントゲン写真から、どのようなSQL文をイメージしますか? また、どのような特徴をもっていると思いますか?

本気で余裕のない師走w なんだこりゃw というアトモスフィアになってきました、体調管理しっかりしないと...

Day 5 へつづく



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

| | | コメント (0)

2019年12月 3日 (火)

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

実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 Day 3のエントリーです.

Day 2 のつづきから.



どのようなSQL文かイメージできたでしょうか? その特徴は?
Id = 2 で INDEX UNIQUE SCAN を行なっている点、Predicate Information に 2 - access("UNIQUE_ID"=1) とあるので、 unique_id列に一意索引または主キー索引があり、 = 1 で一意検索して、得られた行を特定する情報(Oracleの場合ははrowid)を使って、TABLEから該当行をアクセスしているのが id = 1 の TABLE ACCESS BY INDEX ROWID.
Predicate Information には他の情報はリストされていないので、以下のような SQL文をイメージされたとしたら、正解ではないでしょうか。
(ちなみに、SELECTリストは * にしています. SELECTリストに関わる情報は特にないので. 今回は、SQL*Plusのautotraceを利用していますが、SQLモニター等より詳細な情報を取得することができる機能もあります。必要に応じてツールを使い分けることも重要なスキルだと思います)

select * from tab3 where unique_id = 1;

Index-unique-scan

そう言えば、2009か2010年ごろ昔某所某プロジェクトで、SQLから実行計画をイメージする千本ノック(大げさですが)みたいなことを依頼されてやったことがありましてw。その逆をやってるだけですね、これ!w よーく考えたらw

20191201-122138


ということで、Day 3の実行計画というレントゲン写真はこれ!

INDEX RANGE SCAN
Index-range-scan

この実行計画というなのレントゲン写真から、どのようなSQL文をイメージしますか? また、どのような特徴をもっていると思いますか?
今回のAdvent Calendarに絡めたネタにも慣れてきたころだと思うので、このレントゲン写真から自由に読み取ってみてくだしぁ ;)

Day 4 へつづく



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

| | | コメント (0)

2019年12月 2日 (月)

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

実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 Day 2のエントリーです.

まずは、Day 1の答え



以下の実行計画 (SQL*Plusのauto trace機能を利用) は、TABLE ACCESS FULL ではありますが、Execution PlanセクションとStatisticsセクションしかありません。
また、SQL文にWHERE句がある場合、実行計画の補足情報として、Predicate Information (identified by operation id) セクションがリストされます。
このセクションでは述語、つまり、WHERE句に関わる情報がリストされます。
Predicate Information (identified by operation id) セクションが一切リストされていないこのケースでは、WHERE句自体がSQL文中に存在しないことも読み取ることができます。

ということで、以下の3パターンの可能性はなくなりました。理由はすでにお分かりですよね?

2) select * from tab3 where id + 1 = 10;
3) select * from tab3 where id between 1 and 400000;
4) select /*+ FULL(tab3) */ * from tab3 where id between 1 and 10;

結果として、単純な全表走査を行うSQL文である 1) が正解ということになります。

治療の必要は基本的にありませんが、全表走査しているだけで性能要件を満たせない場合には、全表走査を早くするための治療が必要になる場合があります.
必要があって全表走査しているのであれば全表走査は悪ではありません。
(性能要件は事前に問診等で確認しておくことをおすすめします)

1) select * from tab3;

20191130-192926_20191201010101



では、本題であるDay 2のレントゲン写真は、以下!

これには、先ほど解説したばかりのPredicate Information (identified by operation id) がリストされ、2 - access("UNIQUE_ID"=1) という部分から unique_id列でアクセスしていることが読み取れます。

20191201-05116

Id=2のoperationでは、INDEX UNIQUE SCANが行われています。INDEX UNIQUE SCANしている対象オブジェクトは、TAB3_PK です。 INDEX という部分から TAB3_PK は索引であることも読み取れます。
かつ、UNIQUE SCAN ということなので、索引は一意索引または、主キー索引で、一意に値を特定できる索引であることも合わせて読み取れます。

この実行計画という名のレントゲン写真から、どのようなSQL文をイメージしますか? また、どのような特徴をもっていると思いますか?

つづきは、Day 3にて。:)



寒いのも、寒い場所も嫌いですw

| | | コメント (0)

2019年12月 1日 (日)

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

実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 Day1のエントリーです.

Day 1のSQL文のレントゲンはこれ.

TABLE ACCESS FULL

この実行計画にSQL文をイメージしてみましょう. 目を閉じて〜
どのようなSQL文が浮かびましたか?

20191130-192926

1) select * from tab3;

where句がない、とか

2) select * from tab3 where id + 1 = 10;

id列にユニーク索引または主キー作成があったとしても、索引を利用できないような構文だったり、とか

3) select * from tab3 where id between 1 and 400000;

id列にユニーク索引または主キー索引があったとしても、索引スキャンより全表走査が効率良いのでオプティマイザが選択した場合(一般的に30%程度未満が目安ですが)とか

4) select /*+ FULL(tab3) */ * from tab3 where id between 1 and 10;

id列にユニーク索引または主キー索引ががあり、オプティマイザに任せておけば、間違いなく、索引アクセスされるはずなのに、なぜか、FULLヒントが付いている場合とか

といくつかの状況になっている可能性があります。

TABLE ACCESS FULLが妥当な状況であれば、治療不要なわけですが、それ以外の場合、患者さんのリクエストや大人の事情を考慮かつ、治療誓約書にサインいただいたうえでw、治療する必要がありますよね。

今回の実行計画をみて上記のどの状態である可能性が高いでしょうか?

答えは、明日の窓にて。



ついに今年も残すところ今日を含め31日。 今年もいろいろ激動日々だったw
そう言えば、ことしは、飲み会でしか、湘南方面に行ってなかった。

| | | コメント (0)

2019年11月30日 (土)

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

なんとなく、勢いではじめてみました、実行計画は、SQLのレントゲン写真だ! (Oracle Database編)

https://adventar.org/calendars/4737

20191130-194542

なお、12/17分のエントリーは、JPOUG Advent Calendar 2019とクロスポストします。

| | | コメント (0)

2019年11月15日 (金)

JPOUG Advent Calendar 2019 / event

JPOUG Advent Calendar 2019 残り4枠となりました。

師走の風物詩、参加お待ちしております :)
https://adventar.org/calendars/4154
20191115-63227

| | | コメント (0)

2019年11月12日 (火)

JPOUG in 15minutes #9 / 開催告知

おまっとさんでした。

前回の開催から5ヶ月ほど経つ事になりますが、JPOUG in 15minutes #9を開催します。

今回のオーガナイザーには、long time no seeな方々も。

皆様にお会いできることを楽しみにしています、目の前の仕事を片付けつつw

JPOUG in 15 minutes #9

| | | コメント (0)

2018年5月 1日 (火)

Oracle Database入学式 2018 – 保護者の方はご遠慮ください

入学式にしては少々、遅めですがw 今年もOracle Database入学式 2018 行います。

講師は、Oracle ACE 渡部 亮太 氏です。

詳細は以下をご覧ください。 ↓↓↓↓↓↓↓↓↓↓↓↓
Oracle Database入学式 2018 – 保護者の方はご遠慮ください

| | | コメント (0) | トラックバック (0)

2018年4月 2日 (月)

Oracle Database Connect 2018

今年もOracle Database Connect の季節がやってきました!

昨年までの大きな会場での開催ではなく、
日本オラクル青山センターでの開催となります。

Oracle Database Connect 2018 / JPOUG告知ページ
http://www.jpoug.org/2018/03/20/odc2018

そして、私も、雛壇DBエンジニアとして参加予定です(ボケ担当?!)


皆さんと、お会いできることを楽しみにしています :)

20160805_134656

| | | コメント (0) | トラックバック (0)

2017年11月 3日 (金)

JPOUG in 15 minutes #6 2017年11月17日 @ オラクル青山センター 13F

JPOUG in 15 minutes #6を以下の日程で開催します。

2017年11月17日(金)19:00~21:30(開場および受付開始: 18時30分)
東京都港区北青山2-5-8 オラクル青山センター 13階セミナールーム

今回は、Docker縛り。 Dockerを絡めたセッションのみです。
どんな内容になるか、まったくわかりませんが :)

広い会場をお借りしていますので、座席には余裕があります。

お申し込みは以下からどうぞ。
JPOUG in 15 minutes #6 / Doorkeeper


ところで、
昨日開催れた Docker Meet-up #19 @ Rakuten、なんと抽選で当選!1週間で2度目の @ Rakuten
先週土曜日のRakuten Technology Conference 2017も含め、英語風味多めの1週間で脳の疲れMax w

【参考訳】DockerCon EU 17 における Docker の Kubernetes サポート関連発表
https://pocketstudio.net/2017/10/18/docker-kubernetes-translate/

| | | コメント (0) | トラックバック (0)

2017年4月12日 (水)

Oracle Database Connect 2017 : 参加報告とお礼

Oracle Database Connect 2017の資料とセッション映像(全てではないようですが)が公開されました。

このような機会を与えてくれた日本オラクルのしばちょうさん、関係者の皆様ありがとうございました。
ドクターG的な感じで伝えられるか不安でしたが、評判は良かったと聞きホッとしているところです:)

Oracle Database Connect 2017 / jpoug.org

Oracle Database Connect 2017資料
http://www.oracle.com/technetwork/jp/ondemand/odc2017-3627481-ja.html


■基調講演

■異なるデータベース間のSQL比較と Oracle Database 12cの新機能
 日本ヒューレット・パッカード株式会社 篠田典良さん

■クラウド運用で省力化! 最新版 Oracle Database を活用した基盤の魅力
 日本オラクル 伊藤 勝一さん

■進化したのはサーバだけじゃない! DBA の毎日をもっと豊かにするユーティリティのすすめ
 NTTデータ先端技術株式会社 吉田成利さん


Oracle Database Connect 2017 つぶやきまとめ #jpoug #oradbc17
https://togetter.com/li/1088687

■エキスパートはどう考えるか? 体感!パフォーマンスチューニング 
 日本オラクル しばちょうさん、津島さん、畔勝さん
 JPOUG 諸橋さん、渡部さん、そして私


ps.
開催前のミーティングで、「イケる、イケる」と自己暗示のように呟いていた、しばちょうさんが印象的でした:)

| | | コメント (0) | トラックバック (0)

2017年3月 7日 (火)

Oracle Database Connect 2017

Oracle Database Connect 2017 ~ 最新のデータベース技術がここにある ~

が明日開催されます。


昨年は、LTでしたが、今年は好評のJPOUG in 15minitesを行います。
セッション・オーガナイザーはJPOUGのサイトにてご確認ください。
http://www.jpoug.org/2017/02/14/odc2017


アジェンダには記載されていない登壇者は諸橋さんのブログで公開されていますが

ablog - 畔勝さん
wmo6hash::blog - 諸橋さん
コーソル DatabaseエンジニアのBlog - 渡部さん

そして、最近、ひな壇エンジニアリングに目覚めつつあるw 私


会場でお会いできることを楽しみにしています。



あ、そうそう、

昔、奥さんが書いてた「今日のゴハン」ってブログで、ダーリンと書かれてたのですが、
おら!オラ!Oracleのペンネーム:ダーリンが誰なのか知ったのは、2011年か2012年ごろ。

ネタを探してググっていたら、そのダーリンのエントリが!!! 

待ちイベントに関する検証 その7 - ペンネーム: ダーリン
http://www.insight-tec.com/mailmagazine/ora3/vol327.html


| | | コメント (0) | トラックバック (0)

2016年2月 1日 (月)

エンジニアサポートCROSS2016 でパネリストとして参加しまっす

2016/2/5(金曜日)エンジニアサポートCROSS2016 @ 横浜大さん橋ホール「今こそRDBの時代だ!・・いや待て、その前に~最近のRDB四方山話」にて、パネリストとして参加させていただきます。(初参加なのでドキドキです:)

なお、事前登録は無料とのこと。

詳細は以下を御覧ください。
http://2016.cross-party.com




インフルエンザで寝込んたんですが、やっと外出できるようになってほっとしてます!
そして、約1週間分の記憶が....ない、というか空白というか、40度の熱との戦いしか残ってない..
病み明けから全開に持ってかないといけないくらいに仕事が溜まってて余裕ないぞ、どうしよーw

そういえば、イベント前に、Oracle® Spatial and Graph RDFセマンティック・グラフ開発者ガイド 12cリリース1 (12.1)関連の小ネタを書こうかと思ってたが.....それも忘れてた...いずれ書かないと (^^;;;




2016/3/5追記
今こそRDBの時代だ!・・いや待て、その前に~最近のRDB四方山話
http://2016.cross-party.com/program/a1


SQL標準、JSON型、負債… 一流のRDB技術者がクロストーク! #CROSS2016 #CROSS2016a - Togetterまとめ
http://togetter.com/li/934473

| | | コメント (0) | トラックバック (0)

2015年12月 4日 (金)

OTHER_XMLの中身

JPOUG Advent Calendar 2015 - 4日目のエントリーです。

役に立たないから、絶対最後まで読まないでね!!! (^^)

さて、
みなさん、マニュアル読んでますか? 
最近は量が多いので、必要になってから、なりそうだから読むことが多いです。
Oracle® Databaseリファレンス 12cリリース1 (12.1) なんて特にそうです。
ただ、一度読み始めると、いろいろと気づくところもあるわけです...こんな情報が取れるのか! とか。


あ〜、これは、禁断のw マニュアルに記載されてないパラメータを指定すると見れるやつだ!!! とか気づくこともあったり。

例えば、V$SQL_PLANDBA_HIST_SQL_PLANのOTHER_XML列。

この列の説明には実に興味深いことが書かれています。以下の説明、読んでてワクワクしますw 
何が格納されているのでしょう???(もう、みんな知ってるくせに〜)

”アウトライン・データ(同じ計画の再作成に使用できる一連のオプティマイザ・ヒント)”

見たくないですか? 中身。

見たいですよね。私もそうです!


ただ、OTHER_XML列、列名の通り、CLOB型で中身はXMLです!!!
SQL*Plusで普通に表示しようとすると長すぎて読みにくいってのが難点w


ならばXMLにも対応しているSQL文で何とかしてみたいと思います。

ゴニョゴニョ、パタパタ。

できました。

dba_hist_sql_plan向けですが。(v$sql_planビューでも同様のことができます!)
(注:dba_hist_*ビューを参照するにはOracle Diagnostics Packが必要でっす。ですが、v$sql_planを参照するのならオプションはいらないですよね.)

こんな感じです

SYSTEM> !cat report_outline_hints.sql
col outline for a200
set linesize 300
set pagesize 10000
set veri off

SELECT '/*+' AS outline FROM DUAL
UNION ALL
SELECT ' '||'BEGIN_OUTLINE_DATA' FROM DUAL
UNION ALL
SELECT
' '||o.outlinehint
FROM
(
SELECT
EXTRACTVALUE(
VALUE(x)
, '/hint/text()'
) AS outlinehint
FROM
XMLTABLE(
'/*/outline_data/hint'
PASSING(
SELECT
XMLTYPE(other_xml)
FROM
dba_hist_sql_plan
WHERE
other_xml IS NOT NULL
AND sql_id = '&1'
AND plan_hash_value = &2
)
) x
) o
UNION ALL
SELECT ' '||'END_OUTLINE_DATA' FROM DUAL
UNION ALL
SELECT '*/' FROM DUAL
/
set veri on

実行すると以下のような、:) 情報を取り出すことができます!!

SYSTEM> @report_outline_hints gdtyuqcyk8x1c 2236229349

OUTLINE
------------------------------------------------------------------------------------------
/*+
BEGIN_OUTLINE_DATA
IGNORE_OPTIM_EMBEDDED_HINTS
OPTIMIZER_FEATURES_ENABLE('12.1.0.2')
DB_VERSION('12.1.0.2')
ALL_ROWS
OUTLINE_LEAF(@"SEL$2")
OUTLINE_LEAF(@"SEL$1")
INDEX(@"SEL$1" "B"@"SEL$1" ("ILM_EXECUTION$"."EXECUTION_ID"))
NO_ACCESS(@"SEL$1" "A"@"SEL$1")
LEADING(@"SEL$1" "B"@"SEL$1" "A"@"SEL$1")
USE_MERGE(@"SEL$1" "A"@"SEL$1")
PQ_FILTER(@"SEL$1" SERIAL)
INDEX(@"SEL$2" "A"@"SEL$2" ("ILM_EXECUTION$"."EXECUTION_ID"))
FULL(@"SEL$2" "B"@"SEL$2")
LEADING(@"SEL$2" "A"@"SEL$2" "B"@"SEL$2")
USE_MERGE(@"SEL$2" "B"@"SEL$2")
USE_HASH_AGGREGATION(@"SEL$2")
END_OUTLINE_DATA
*/

表示された内容に、身に覚え、
いや、見覚えのある方も多いことと思います :) あれでね。そう、あれです。
マニュアルに記載されいないパラメータを利用しなくても取り出せるんです。

ついでなので、マニュアルに記載のないパラメータを使ったDBMS_XPLAN.DISPLAY_AWRで同じ情報をリストしてみました。DBMS_XPLAN.DISPLAY_AWR以外のDISPLAY*関数のformatパラメータでもできます:)
(注: DISPLAY_AWRでAWRを参照するのでOracle Diagnostics Packが必要でっす。 ですが、DISPLAY_CURSOR(),DISPLAY()とDISPLAY_PLAN()ならAWRは参照しないのでオプションはいらないですよね。)

PROMPT
PROMPT ****** display_awr with outline option *********
SELECT
plan_table_output as outline
FROM
TABLE(DBMS_XPLAN.DISPLAY_AWR(sql_id=>'&1',plan_hash_value=>&2,format=>'OUTLINE'))
/


****** DBMS_XPLAN.DISPLAY_AWR with OUTLINE option *******

OUTLINE
------------------------------------------------------------------------------------------
SQL_ID gdtyuqcyk8x1c
--------------------
SELECT B.EXECUTION_ID, NVL(A.N_COUNT,0), A.COMP_TIME FROM ( SELECT
A.EXECUTION_ID, COUNT(*) N_COUNT, NVL(MAX(B.COMPLETION_TIME), SYSDATE)
COMP_TIME FROM SYS.ILM_EXECUTION$ A, SYS.ILM_RESULTS$ B WHERE
EXECUTION_STATE = :B7 AND A.EXECUTION_ID = B.EXECUTION_ID AND
B.JOB_STATUS NOT IN (:B6 , :B5 , :B4 , :B3 , :B2 , :B1 ) GROUP BY
A.EXECUTION_ID )A, ILM_EXECUTION$ B WHERE B.EXECUTION_ID =
A.EXECUTION_ID (+) AND EXECUTION_STATE = :B7 AND (ROWNUM <= :B9 OR :B9
= :B8 )

Plan hash value: 2236229349

-----------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 4 (100)| |
| 1 | COUNT | | | | | |
| 2 | FILTER | | | | | |
| 3 | MERGE JOIN OUTER | | 1 | 65 | 4 (50)| 00:00:01 |
| 4 | TABLE ACCESS BY INDEX ROWID | ILM_EXECUTION$ | 1 | 26 | 0 (0)| |
| 5 | INDEX FULL SCAN | PK_TASKID | 1 | | 0 (0)| |
| 6 | SORT JOIN | | 1 | 39 | 4 (50)| 00:00:01 |
| 7 | VIEW | | 1 | 39 | 3 (34)| 00:00:01 |
| 8 | HASH GROUP BY | | 1 | 65 | 3 (34)| 00:00:01 |
| 9 | MERGE JOIN | | 1 | 65 | 3 (34)| 00:00:01 |
| 10 | TABLE ACCESS BY INDEX ROWID| ILM_EXECUTION$ | 1 | 26 | 0 (0)| |
| 11 | INDEX FULL SCAN | PK_TASKID | 1 | | 0 (0)| |
| 12 | SORT JOIN | | 1 | 39 | 3 (34)| 00:00:01 |
| 13 | TABLE ACCESS FULL | ILM_RESULTS$ | 1 | 39 | 2 (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------------

Outline Data
-------------

/*+
BEGIN_OUTLINE_DATA
IGNORE_OPTIM_EMBEDDED_HINTS
OPTIMIZER_FEATURES_ENABLE('12.1.0.2')
DB_VERSION('12.1.0.2')
ALL_ROWS
OUTLINE_LEAF(@"SEL$2")
OUTLINE_LEAF(@"SEL$1")
INDEX(@"SEL$1" "B"@"SEL$1" ("ILM_EXECUTION$"."EXECUTION_ID"))
NO_ACCESS(@"SEL$1" "A"@"SEL$1")
LEADING(@"SEL$1" "B"@"SEL$1" "A"@"SEL$1")
USE_MERGE(@"SEL$1" "A"@"SEL$1")
PQ_FILTER(@"SEL$1" SERIAL)
INDEX(@"SEL$2" "A"@"SEL$2" ("ILM_EXECUTION$"."EXECUTION_ID"))
FULL(@"SEL$2" "B"@"SEL$2")
LEADING(@"SEL$2" "A"@"SEL$2" "B"@"SEL$2")
USE_MERGE(@"SEL$2" "B"@"SEL$2")
USE_HASH_AGGREGATION(@"SEL$2")
END_OUTLINE_DATA
*/

ちなみに、11g R2でも動作します!


どうでしたか?役に立たなかったですよね?
以上、OUTLINE HINTSより愛を込めてお送りしました!



参考: (日本語で書かれたエントリーは見当たらない。初か、もしかして!w)

Oracle SQL Plan Stability
http://blog.tanelpoder.com/oracle/performance/sql/oracle-sql-plan-stability/


Plan stability in 10g - using existing cursors to create Stored Outlines and SQL profiles
http://oracle-randolf.blogspot.jp/2009/03/plan-stability-in-10g-using-existing.html


FORCE_MATCH for Stored Outlines and/or SQL Baselines????? – follow up
https://tonyhasler.wordpress.com/2011/12/

How to hint – 1
https://jonathanlewis.wordpress.com/2011/06/08/how-to-hint-1/

dbms_xplan(3)
https://jonathanlewis.wordpress.com/2008/03/06/dbms_xplan3/



追記:

@yoshikawさんに指摘され、EXTRACTVALUE()が11.2で非推奨になっていたとことに気づく orz.

@yoshikawさん、指摘ありがとうございます。 

XMLTABLE().... COLUMNSを使えばEXTRACTVALUE()はいらなかった!!!! ということでEXTRACTVALUEなし版も作りました!!

ただ、CON_IDも見ないとマルチテナントに対応できず、エラーになると気づいたが、
11gにも対応しようとすると、もう一工夫必要なことに気づき、再び、orz.

つづきは、...いずれ...

変更したSQL文は以下のとおり。

SYSTEM> !cat report_outline_hints.sql
col outline for a200
set linesize 300
set pagesize 10000
set veri off

SELECT '/*+' AS outline FROM dual
UNION ALL
SELECT ' '||'BEGIN_OUTLINE_DATA' FROM DUAL
UNION ALL
SELECT
' '||x.outline_hint
FROM
XMLTABLE(
'/*/outline_data/hint/text()'
PASSING(
SELECT
XMLTYPE(other_xml)
FROM
dba_hist_sql_plan
WHERE
other_xml IS NOT NULL
AND sql_id = '&1'
AND plan_hash_value = &2
)
COLUMNS outline_hint PATH '/text()'
) x
UNION ALL
SELECT ' '||'END_OUTLINE_DATA' FROM DUAL
UNION ALL
SELECT '*/' FROM DUAL
/

SYSTEM> @report_outline_hints gdtyuqcyk8x1c 2236229349

OUTLINE
--------------------------------------------------------------------------------
/*+
BEGIN_OUTLINE_DATA
IGNORE_OPTIM_EMBEDDED_HINTS
OPTIMIZER_FEATURES_ENABLE('12.1.0.2')
DB_VERSION('12.1.0.2')
ALL_ROWS
OUTLINE_LEAF(@"SEL$2")
OUTLINE_LEAF(@"SEL$1")
INDEX(@"SEL$1" "B"@"SEL$1" ("ILM_EXECUTION$"."EXECUTION_ID"))
NO_ACCESS(@"SEL$1" "A"@"SEL$1")
LEADING(@"SEL$1" "B"@"SEL$1" "A"@"SEL$1")
USE_MERGE(@"SEL$1" "A"@"SEL$1")
PQ_FILTER(@"SEL$1" SERIAL)
INDEX(@"SEL$2" "A"@"SEL$2" ("ILM_EXECUTION$"."EXECUTION_ID"))
FULL(@"SEL$2" "B"@"SEL$2")
LEADING(@"SEL$2" "A"@"SEL$2" "B"@"SEL$2")
USE_MERGE(@"SEL$2" "B"@"SEL$2")
USE_HASH_AGGREGATION(@"SEL$2")
END_OUTLINE_DATA
*/

JPOUG Advent Calendar 2015、12/5は、Yohei Azekatsu さんです。どんな変態ネタが飛び出すのか、乞うご期待!!

| | | コメント (0) | トラックバック (0)

2015年10月 1日 (木)

JPOUG> SET EVENTS 20151017 を開催します!

JPOUG主催

JPOUG> SET EVENTS 20151017

を日本オラクル青山センター 13階セミナールームで
2015年10月17日(土)13:00~17:30(開場および受付開始: 12:30)に開催します。

ハッシュタグ #JPOUG

今回は、
開発設計、チューニング関連の力セッション、インフラ関連の技セッション、入門者向けの知セッションと3本立てです。

JPOUGボードメンバーでもある渡部さん、通しで3枠!!  知セッションを担当します!
Oracle Database 入学式のような感じになるのでしょうか? Oracle Database初心者におすすめです。


そして、ミックさんをはじめ、JPOUG主催イベント初登場のスピーカーが多いのも今回の特徴です。


セッションの詳細は以下サイトをご覧ください。
http://www.jpoug.org/2015/09/01/setevents20151017
Logo20151017_851x478

私は裏方ですので、うろうろしているか、受付とか、やってると思います :)




ところで、皆さん。 Oracle Database 7.3とOracle Database 12.1のSELECT文がどれだけ進化、複雑化したかイメージできてますか?

SELECT文があれば更新削除以外は、なんでもできるんじゃないかと、錯覚するほと変わってきています。
これから先も変化すると思います。(基本は同じですが。)

付いていけてますか?  

まさか、Oracle Database 7.3とか、8とか8iぐらいのSELECT文で止まったままになってないでしょうか?
使いこなせてますか?

たまに、自問自答してます......

Oracle Database 7.3とOracle Database 12.1のSELECT文の文法の差をこうやってみると.....お・ど・ろ・き・ま・す・よ!!!!

20150926_223247




7.3と12.1のSELECT文の差の詳細はマニュアルで!

Oracle Database 7.3 SQL Reference
Oracle Database 12.1 SQL Reference - SELECT

| | | コメント (0) | トラックバック (0)

2014年11月19日 (水)

SQLチューニング総合診療所 ケースファイルX / db tech showcase tokyo 2014

恒例となってきたデータベースのお祭り db tech showcase tokyo

今年も、JPOUGのSQLチューニング総合診療医w として治療話をしてきました :)

20141119_222101


貴重な機会を提供いただいたインサイトテクノロジーの皆様、そして、お忙しい中、セッションに参加してくださった皆様、ありがとうございました。

当日は気合で乗り切ったものの翌日は力尽きて発熱で資料アップが遅れていましたが
L35 「SQLチューニング総合診療所 ケースファイルX」の資料をslideshareに公開しました。

来年のお祭りを楽しみにしています:)


あ、そうそう、
Craig Shallahamer さんのセッションを聴講したときに感じたのですが、「本人が楽しそうに話す」の重要!!
ですね。 :)



2013年以前のセッション資料は以下から。

- db tech showcase tokyo 2013 - A35 - JPOUG特濃:潮溜まりでジャブジャブ、SQLチューニング Tweet
- Unconference at db tech showcase 2012の資料公開 :)

| | | コメント (0) | トラックバック (0)

2014年8月26日 (火)

JPOUG> SET EVENTS 20140907 開催を開催します! 

2014年9月7日(日)13:00~17:00(開場および受付開始: 12:30)に、
IIJさんに会場をお借りし、JPOUG> SET EVNETS 20140907を開催します。

参加方法やプログラムの詳細は、JPOUG> SET EVENTS 20140907をご覧ください。

では、会場でお会いしましょう。 (^^)/  <<<恐らく受け付けをやっていると思います :)

Jpougsetevents20140907w902

| | | コメント (0) | トラックバック (0)

2014年6月28日 (土)

InterSystems Symposia 2014に行ってきた

db tech showcase 2014 Osakaより先だったのだけど...
InterSystems Symposia 2014に行ってきた。という話。

CachéはSQLでアクセスする必要はないのだけど、RDBMSからの乗り換え組でSQLから乗り換えコストの低減目的で導入されたインターフェースだというのは間違いなし、
昔からM言語をやってきた人達からすれば、SQLアクセスだと! はぁ〜? 的な感じも無くはないし、おまけ的なイメージは強いんだろうな。
その分のオーバーヘッドもあるしな〜。 と思ってたのですが....

最近の動きを見ているとSQLアクセスにも本気なのかな。と思わせる様子があるんだよね。

Caché SQL 最新情報の資料P3部分でダイレクトアクセス(元からあるNoSQLな部分)とSQLアクセスのメリット、デメリットの解説やビットマップインデックスのメンテナンス機能。

20140628_124018
Caché SQL 最新情報のセッション資料は上のリンクからダウンロードできますよ!


そして、 Push Subquery Conditions into UNION LegsなどのSQL実行計画最適化、OracleのUSE_CONCAT相当など多数のヒント、パラレルクエリなど"おまけのインターフェース"とは思えなくなってきた感がある。


ちなみに、Caché自体はスパース多次元配列なので行指向、列指向のようなことはないんだけど、列指向的な加工もできちゃうわけで、それはそれで面白いかなと、勝ってに妄想してみたりw

たまには、右脳を活性化しないとね、イメージ力大事 :)

| | | コメント (0) | トラックバック (0)

2014年6月21日 (土)

db tech showcase 2014 Osaka に行ってきた

I love your data(どこかのパクリw) な人たちが、いろいろなDBMSを見聞きし、それぞれの思いで、何年か先の未来に、それぞれの思いを馳せる

そんな、集まりが、 db tech showcase 2014 Osaka 

(ん....俺っぽくない出だしを書いててワロタ....)


に臨時休業(自分ではこれも仕事のうちなんだがw 仕事って思ってないだけw)して参加した。
https://www.facebook.com/db.tech.showcase

Slideshare : セッション資料はここ


話を聞いていたら、オレオレレプリケーションできそうな気になるから不思議 :) .
オレオレ、ゴルゲやオレオレ、attunityとか、自分で作って試してみると、面倒くさいポイントとか見えていいかもね。
Attunity Replicateの画面を初めてみたけど、シンプルで好きなデザイン。
B31 : LogMinerってレプリケーションソフトで使われてるけどどうなってる? / 森田俊哉(インサイトテクノロジー)


Oracle以外の話も聴きたくてNoSQL系などをチョイス。 割り切った実装で特定用途でその力を発揮する。割り切り大事。
D32 : Amazon Redshift Deep Dive / 大久保順(アマゾンデータサービスジャパン)


B33 : Riak: 本物の高可用性を実現する仕組みとは? / 佐藤 貴彦 (Bashoジャパン)


D34 : データウェアハウス・エンジンTeradataのご紹介とビッグデータ統合アーキテクチャー / 山本 泰史(日本テラデータ)


The Machine!にも関連するのだろうけど、Memristorの話題も!
D35 : インメモリーデータベース徹底比較 / 小森博之(日本HP)


そしてスペシャルセッション、遠い未来じゃないはなし
A36 : ウエアラブルとO2Oが切り拓くICTの新地平 / 村上憲郎

vessylもそんな”もの”の一つかもしれない。飲みものの分析ができるんだからトイレにも応用できるんじゃないか的な :)
日本のトイレがそうなるかは分からないけど、先にやってくれたら面白いかもね。
毎日が健康診断、データはかかりつけの医師に共有されていて、気になるデータが見つかると、洗面台のミラー風マルチタッチデバイスに情報がプッシュされ...必要なら、その場で通院予約、その後待たされることなく診察なんて時間の無駄がなくていいな〜と、ぼーっと妄想していたり。

楽しいやね。 :)

そういえばそんなシーンのある映画で思い出したのがこれ




T-シャツ、ありがとうございました。


Bqilsptcyaae4vjjpglarge

東京から大阪への新幹線で日帰りだと電池切れ感が半端ないので一泊することをおすすめしますw


| | | コメント (0) | トラックバック (0)

2013年12月 9日 (月)

no ocijdbc11 in java.library.path on OS X Mavericks

JPOUG Advent Calendar 2013、9日目のエントリー、かつ、チューニングネタではなく Java on OS X の話という変化球 :) です。

OS X版Oracle SQL DeveloperやOracle JDeveloperで、OCI/Thick JDBCを利用しようとして以下のようなメッセージに遭遇したら...みなさんどうしてるのだろう? 

no ocijdbc11 in java.library.path

と考えだしたら眠れなくなったので、役に立つのか、たたないのかわからないけど書いておきます

私は、Oracle SQL DeveloperやOracle JDeveloperの起動シェルでDYLD_LIBRARY_PATHなどの環境変数をセットすることで対処しています。
(今となってはこれが楽だと思います。 environment.plistでなんとかできた時代もありましたけど...いまは使えないしね)

no ocijdbc11 in java.library.pathとなっている状態から解決するまでの操作をYouTubeで....


映像では、ユーザーのホームディレクトリーにOracle向け環境変数設定ファイル (この例では、oracleenvというファイルを作成してあります) を作成しておき、その設定ファイルをOracle SQL Developer等の起動シェルで読み込ませて問題を解決するまでの操作を行っています。

主演
MacBook Air (mid2013)

ホストOS、その他

  • OS X 10.9 Maveriks
  • Oracle Instant Client 11g 11.2.0.3.0 for OS X (64bit)
  • Terminal 2.4
  • VirtualBox 4.3.4 for OS X
  • Oracle SQL Developer 4.0.0 for OS X
  • Oracle JDeveloper12c 12.1.2.0.0 Studio Edition Generic

ゲストOS、その他

  • Oracle Linux Server 6.4 x86_64
  • Oracle Database 12c EE R1 for Linux x86_64

映像では見づらい方向けの解説。

事前にOracle向け設定ファイルを該当ユーザーのホームディレクトリーに作成しておきます。
この例では、oracleenvとして作成しました。(不過視ファイルとしてもよいかもしれません。)
Oracle_environment_variables


Oracle SQL Developer 4.0 for OS X

「Oracle SQL Developerメニュー」→「Preference...」を選択
002_sdev_004

「データベース」→「拡張」→「OCI/Thickドライバの使用」チェックボックス」をチェック→「テスト」ボタンをクリック
002_sdev_005

no ocijdbc11 in java.library.pathエラーとなる(ライブラリーへのパスが通ってないので当然ですよね)
002_sdev_006

「Finder」→「アプリケーション」→「SQL Developer」→「右クリック」→ポップアップメニューの「パッケージの内容表示」
002_sdev_009

「Contents」→「MacOS」→「sqldeveloper.sh」を選択
002_sdev_010

ポップアップメニュー「このアプリケーションで開く」でお好きなテキストエティタを選択
002_sdev_012

oracle向け環境設定ファイルを読み込ませるように編集。この例ではユーザーホームディレクトリにある oracleenvというファイルを読み込むように変更。
002_sdev_013

Oracle SQL Developer 4.0を再起動しOCI/Thick JDBCドライバーで接続可能か再確認
002_sdev_014

002_sdev_015


Oracle JDeveloper12c 12.1.2.0.0 Studio Edition Generic

「データベース接続編集」ダイアログの「接続のテスト」ボタンをクリックするとno ocijdbc11 in java.library.pathエラー(これもパスが通ってないのが原因なので...)
003_jdev_002

003_jdev_003

「Finder」でOracle JDeveloper12cのインストールディレクトリーからアプリケーション「JDeveloper」を右クリック
→ポップアップメニューの「パッケージの内容を表示」を選択

003_jdev_004

「Contents」→「MacOS」→「JDeveloper」を選択して右クリック→「このアプリケーションを開く」でお好きなテキストエディタを選択
003_jdev_005

oracle向け環境設定ファイルを読み込ませるように編集。この例ではユーザーホームディレクトリにある oracleenvというファイルを読み込むように変更。
003_jdev_006

Oracle JDeveloper12cを再起動し、OCI/Thick JDBCドライバーで接続可能か再確認
003_jdev_007

003_jdev_008


明日は、@dekasasaki さんの担当です。引き続き、JPOUG Advent Calendar 2013をお楽しみください。:)


| | | コメント (0) | トラックバック (0)

2013年11月17日 (日)

db tech showcase tokyo 2013 - A35 - JPOUG特濃:潮溜まりでジャブジャブ、SQLチューニング

11/13〜15に開催されたdb tech showcase tokyo 2013 の最終日、午後の4枠で特濃JPOUGとてセッションを行いました。

貴重な機会を提供いただいたインサイトテクノロジーの皆様ありがとうございました。
また、お忙しい中、セッションに参加してくださった皆様、ありがとうございました。

A35
15:00-15:45 / 「JPOUG特濃:潮溜まりでジャブジャブ、SQLチューニング」 のセッション資料を公開しました。

塩分濃いめの潮溜まりで釣り上げたSQLは治療できるかどうかもわからない病になっていました….
治療できたか、できなかったのか……

曲者すぎる難病もありますが、何かの機会に思い出していただければと思います。

みなさん、楽しい時間をありがとう。

| | | コメント (0) | トラックバック (0)

2013年5月15日 (水)

db tech showcase 大阪 2013 へ“技術者魂”を届けます。

インサイトテクノロジーさん主催

db tech showcase 大阪 2013 へ“技術者魂”を届けます。


当日、私は、大阪へ”酒”飲み(だけ)に行けるでしょうかw (謎

| | | コメント (0) | トラックバック (0)

2012年10月21日 (日)

Unconference at db tech showcase 2012の資料公開 :)

db tech showcase 2012
Unconference at db tech showcase 2012

db tech showcaseの一角をJPOUGが占拠してUnconferenceを開催しました。 db tech showcase関係者の皆様、このような機会を与えて頂き大変感謝します。
そして、お疲れさまでした。



Index Only Access 3部作の最終回?! として 「Index Only Accessが実装されるたった一つの理由」と題したセッションを行いました。
実行計画を取得するために操作したデータベースの中には人生二度目のデータベース複数もあり、かなりの時間を裂いて調べた割にはセッション時間が少々短めになってしまいました。m(_ _)m

なぜ、このテーマを選んだか.

PostgreSQLがリリースされてから9.1まで実装されなかったIndex Only Accessでしたが、9.2でついに実装されました。

そして..db tech showcase 2012は...

SQL> select dbms_name from all_dbms where dbms_category like "%";

DBMS_NAME
------------------
Oracle
DB2
MySQL
PostgreSQL
SQL Server
Vecterwise
MongoDB
Symfoware
Clustrix
InfiniDB
.
.
.
.

的な雰囲気となっていることもあり、Index Only Accessの魚拓をあつめて比較、Index Only Accessが実装される理由について今一度、考えてみたいな..と。
タイトル見ただけで理由が想像できた方は、資料見なくても大丈夫だと思いますよ。:) 
 

H/Wの性能が急速に伸びてきている影響もあるように感じますが、無駄に広範囲な検索や、無駄にビッグなデータとなっていること気にしていないのではないか? というケースが多くなっていると感じています。
DBMSはアクセスするデータをより少なくするための工夫をしているのに...エンジニアがそれをうまく使っていない、使えていない、設計できてない...そんな"感じ"がするんです。

セッション資料を公開しました。
S1a


じゃ、like "%てない" 状況をどうすればいいか....答えは、小田さんのセッションの中にあった。。。。:)


#不慣れなDBMSもあり、こんなメトリックみたほうが分かりやすいよ〜、などのツッコミ歓迎します.


| | | コメント (0) | トラックバック (0)

2012年7月22日 (日)

JPOUG SET EVENTS 20120721 - 「(続)いん!、イン!、Index 大人の事情縛りのSQLチューニング」資料公開

当日は、予想を大きく上回るご参加、ありがとうございました。m(_ _)m  エンジニアの笑顔っていいですよね。

※数日前まで風邪で体調を崩していたこもあり名刺切れしていた申し訳ありませんでした。(名刺印刷をアウトソースしないこだわり名刺というのもその理由なのですが。)

JPOUG> SET EVENTS 20120721 @ 日本オラクル青山センター
でのセッション「(続)いん!、イン!、Index 大人の事情縛りのSQLチューニング」の資料を公開します。

Safari以外のブラウザではアニメーション効果はありませんが、Safari (Mac/iPad/iPhone)ではKeynote風(但し、ページ間のトランジッションなし)に表示されます。

デモ環境は前回と同じです。
デモ内容は別途追加予定です。2012/7/24:デモを追加しました。)

いん!、イン!、Index どっぷり Inde Only Access生活w - Oracle OpenWorld Unconference presented by JPOUGのセッション資料はこちら

おまけの資料(OracleとNULL)

Oracle8i SQL Reference Release 8.1.5 - Nulls


Oracle® Database SQL言語リファレンス 11gリリース2(11.2) - NULL


20120722_92335


DEMO : 1回で2万行参照するバッチ処理

ほんとのバッチはこんなもんじゃないのは知ってますよねw.

SCOTT> @demo1_2
1 declare
2 type t_unique_id is table of tab1.unique_id%type index by pls_integer;
3 type t_non_unique_id is table of tab1.non_unique_id%type index by pls_integer;
4 unique_ids t_unique_id;
5 non_unique_ids t_non_unique_id;
6 begin
7 select
8 unique_id
9 ,non_unique_id
10 bulk collect into
11 unique_ids
12 ,non_unique_ids
13 from
14 tab1
15 where
16 unique_id between 1 and 20000
17 and is_delete = 0
18 and status_code = '00'
19 ;
20 dbms_output.put_line('rows:'||unique_ids.last);
21* end;
rows:20000

PL/SQLプロシージャが正常に完了しました。

経過: 00:00:00.75

・・・中略・・・

Plan Statistics DB/Inst: DISCUS/discus Snaps: 208-209
-> % Total DB Time is the Elapsed Time of the SQL statement divided
into the Total Database Time multiplied by 100

Stat Name Statement Per Execution % Snap
---------------------------------------- ---------- -------------- -------
Elapsed Time (ms) 699 699.0 22.4
CPU Time (ms) 310 310.0 16.3
Executions 1 N/A N/A
Buffer Gets 1,648 1,648.0 7.9
Disk Reads 1,584 1,584.0 65.0
Parse Calls 1 1.0 0.1
Rows 20,000 20,000.0 N/A
User I/O Wait Time (ms) 585 N/A N/A
Cluster Wait Time (ms) 0 N/A N/A
Application Wait Time (ms) 0 N/A N/A
Concurrency Wait Time (ms) 0 N/A N/A
Invalidations 0 N/A N/A
Version Count 1 N/A N/A
Sharable Mem(KB) 14 N/A N/A
-------------------------------------------------------------

Execution Plan
---------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 1579 (100)| |
| 1 | TABLE ACCESS BY INDEX ROWID| TAB1 | 20000 | 273K| 1579 (1)| 00:00:19 |
| 2 | INDEX RANGE SCAN | TAB1_PK | 20000 | | 39 (0)| 00:00:01 |
---------------------------------------------------------------------------------------

Full SQL Text

SQL ID SQL Text
------------ -----------------------------------------------------------------
cbmpgdpxr6vy SELECT UNIQUE_ID , NON_UNIQUE_ID FROM TAB1 WHERE UNIQUE_ID BETWEE
EN 1 AND 20000 AND IS_DELETE = 0 AND STATUS_CODE = '00'

Report written to demo1_2_awrsqrpt.txt
SCOTT>


DEMO : 1行の参照を2万回グルグル回すバッチ処理

単純な比較だからね。1回 vs. 2万回グルグル系の。
グルグル回す処理方式もいろいろな大人の事情で利用する必要があるのもこともわかっていますが、基本的に性能はでないので、それを想定した対処は必要ですよね :)

SCOTT> @demo1_3
1 declare
2 type t_unique_id is table of tab1.unique_id%type index by pls_integer;
3 type t_non_unique_id is table of tab1.non_unique_id%type index by pls_integer;
4 unique_ids t_unique_id;
5 non_unique_ids t_non_unique_id;
6 cursor c1(p_unique_id tab1.unique_id%TYPE) is
7 select
8 unique_id
9 ,non_unique_id
10 from
11 tab1
12 where
13 unique_id = p_unique_id
14 and is_delete = 0
15 and status_code = '00'
16 ;
17 begin
18 for i in 1..20000 loop
19 for c1_rec in c1(i) loop
20 unique_ids(i) := c1_rec.unique_id;
21 non_unique_ids(i) := c1_rec.non_unique_id;
22 end loop;
23 end loop;
24 dbms_output.put_line('rows:'||unique_ids.last);
25* end;
rows:20000

PL/SQLプロシージャが正常に完了しました。

・・・中略・・・

Plan Statistics DB/Inst: DISCUS/discus Snaps: 210-211
-> % Total DB Time is the Elapsed Time of the SQL statement divided
into the Total Database Time multiplied by 100

Stat Name Statement Per Execution % Snap
---------------------------------------- ---------- -------------- -------
Elapsed Time (ms) 1,456 0.1 37.4
CPU Time (ms) 1,112 0.1 42.2
Executions 20,000 N/A N/A
Buffer Gets 60,047 3.0 95.3
Disk Reads 1,587 0.1 75.6
Parse Calls 1 0.0 0.7
Rows 20,000 1.0 N/A
User I/O Wait Time (ms) 866 N/A N/A
Cluster Wait Time (ms) 0 N/A N/A
Application Wait Time (ms) 0 N/A N/A
Concurrency Wait Time (ms) 0 N/A N/A
Invalidations 0 N/A N/A
Version Count 1 N/A N/A
Sharable Mem(KB) 18 N/A N/A
-------------------------------------------------------------

Execution Plan
---------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 2 (100)| |
| 1 | TABLE ACCESS BY INDEX ROWID| TAB1 | 1 | 14 | 2 (0)| 00:00:01 |
| 2 | INDEX UNIQUE SCAN | TAB1_PK | 1 | | 1 (0)| 00:00:01 |
---------------------------------------------------------------------------------------

Full SQL Text

SQL ID SQL Text
------------ -----------------------------------------------------------------
dvpjay9p4csj SELECT UNIQUE_ID , NON_UNIQUE_ID FROM TAB1 WHERE UNIQUE_ID = :B1
AND IS_DELETE = 0 AND STATUS_CODE = '00'


Report written to demo1_3_awrsqrpt.txt
SCOTT>

DEMO : DEMO : 1行の参照を2万回グルグル回すバッチ処理をIndex Only Accessでチューニングしたみたよ:)

アクセスブロック数も減ったし、処理時間も短くなった。 グルグル系のはね、SQL文レベルのチューニング限界でもある。
Index Only Accessでチューニングしても、グルグル回ってる回数は同じだから。

SCOTT> @demo1_3_ix
create index tab1_ix_demo1_3 on tab1(unique_id,is_delete,status_code,non_unique_id) nologging;

索引が作成されました。

SCOTT> @demo1_3
1 declare
2 type t_unique_id is table of tab1.unique_id%type index by pls_integer;
3 type t_non_unique_id is table of tab1.non_unique_id%type index by pls_integer;
4 unique_ids t_unique_id;
5 non_unique_ids t_non_unique_id;
6 cursor c1(p_unique_id tab1.unique_id%TYPE) is
7 select
8 unique_id
9 ,non_unique_id
10 from
11 tab1
12 where
13 unique_id = p_unique_id
14 and is_delete = 0
15 and status_code = '00'
16 ;
17 begin
18 for i in 1..20000 loop
19 for c1_rec in c1(i) loop
20 unique_ids(i) := c1_rec.unique_id;
21 non_unique_ids(i) := c1_rec.non_unique_id;
22 end loop;
23 end loop;
24 dbms_output.put_line('rows:'||unique_ids.last);
25* end;
rows:20000

PL/SQLプロシージャが正常に完了しました。

・・・中略・・・

Plan Statistics DB/Inst: DISCUS/discus Snaps: 212-213
-> % Total DB Time is the Elapsed Time of the SQL statement divided
into the Total Database Time multiplied by 100

Stat Name Statement Per Execution % Snap
---------------------------------------- ---------- -------------- -------
Elapsed Time (ms) 498 0.0 11.1
CPU Time (ms) 453 0.0 13.0
Executions 20,000 N/A N/A
Buffer Gets 40,088 2.0 74.9
Disk Reads 72 0.0 8.1
Parse Calls 1 0.0 0.2
Rows 20,000 1.0 N/A
User I/O Wait Time (ms) 37 N/A N/A
Cluster Wait Time (ms) 0 N/A N/A
Application Wait Time (ms) 0 N/A N/A
Concurrency Wait Time (ms) 0 N/A N/A
Invalidations 0 N/A N/A
Version Count 1 N/A N/A
Sharable Mem(KB) 18 N/A N/A
-------------------------------------------------------------

Execution Plan
------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 1 (100)| |
| 1 | INDEX RANGE SCAN| TAB1_IX_DEMO1_3 | 1 | 14 | 1 (0)| 00:00:01 |
------------------------------------------------------------------------------------

Full SQL Text

SQL ID SQL Text
------------ -----------------------------------------------------------------
dvpjay9p4csj SELECT UNIQUE_ID , NON_UNIQUE_ID FROM TAB1 WHERE UNIQUE_ID = :B1
AND IS_DELETE = 0 AND STATUS_CODE = '00'


Report written to demo1_3_awrsqrpt.txt
SCOTT>
SCOTT> @drop_demo1_3_ix
drop index tab1_ix_demo1_3;

索引が削除されました。

DEMO : 暴走するスカラー副問合せ

SELECTリストにあるスカラー副問合せって、クエリ本体でヒットしたデータ件数分グルグル実行されるんだお。

SCOTT> @demo5
alter system flush buffer_cache;

システムが変更されました。

経過: 00:00:00.26
1 select
2 t1.unique_id,
3 t1.item_code,
4 (
5 select
6 max(t3.unique_id)
7 from
8 tab31 t2 join tab311 t3
9 on
10 t3.sub_item_code = t2.sub_item_code
11 and t3.is_delete = 0
12 where
13 t2.item_code = t1.item_code
14 and t2.is_delete = 0
15 ) current_item
16 from
17 tab3 t1
18 where
19 t1.unique_id between 1 and 10000
20 and t1.is_delete = 0
21* and t1.status_code = '00'

10000行が選択されました。

経過: 00:00:17.54

実行計画
----------------------------------------------------------
Plan hash value: 2850625377

-------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 9998 | 253K| 424 (0)| 00:00:06 |
| 1 | SORT AGGREGATE | | 1 | 47 | | |
| 2 | NESTED LOOPS | | 2 | 94 | 8 (0)| 00:00:01 |
|* 3 | TABLE ACCESS BY INDEX ROWID| TAB31 | 1 | 29 | 3 (0)| 00:00:01 |
|* 4 | INDEX UNIQUE SCAN | TAB31_PK | 1 | | 2 (0)| 00:00:01 |
|* 5 | TABLE ACCESS BY INDEX ROWID| TAB311 | 2 | 36 | 5 (0)| 00:00:01 |
|* 6 | INDEX RANGE SCAN | TAB311_IX | 2 | | 2 (0)| 00:00:01 |
|* 7 | TABLE ACCESS BY INDEX ROWID | TAB3 | 9998 | 253K| 424 (0)| 00:00:06 |
|* 8 | INDEX RANGE SCAN | TAB3_PK | 10000 | | 23 (0)| 00:00:01 |
-------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

3 - filter("T2"."IS_DELETE"=0)
4 - access("T2"."ITEM_CODE"=:B1)
5 - filter("T3"."IS_DELETE"=0)
6 - access("T3"."SUB_ITEM_CODE"="T2"."SUB_ITEM_CODE")
7 - filter("T1"."IS_DELETE"=0 AND "T1"."STATUS_CODE"='00')
8 - access("T1"."UNIQUE_ID">=1 AND "T1"."UNIQUE_ID"<=10000)


統計
----------------------------------------------------------
1256 recursive calls
0 db block gets
52747 consistent gets
22557 physical reads
116 redo size
326816 bytes sent via SQL*Net to client
7742 bytes received via SQL*Net from client
668 SQL*Net roundtrips to/from client
35 sorts (memory)
0 sorts (disk)
10000 rows processed

SCOTT>

DEMO : 暴走するスカラー副問合せをIndex Only Accessでチューニング!

アクセスブロック数が明らかに減った :) 索引だけ参照させることでね :)

SCOTT> @demo5_ix
create index tab31_demo_ix on tab31(item_code, is_delete, sub_item_code) nologging;

索引が作成されました。

経過: 00:00:01.18
create index tab311_demo_ix on tab311(sub_item_code, is_delete, unique_id) nologging;

索引が作成されました。

SCOTT> @demo5
alter systen flush buffer_cache;

システムが変更されました。

経過: 00:00:00.18
1 select
2 t1.unique_id,
3 t1.item_code,
4 (
5 select
6 max(t3.unique_id)
7 from
8 tab31 t2 join tab311 t3
9 on
10 t3.sub_item_code = t2.sub_item_code
11 and t3.is_delete = 0
12 where
13 t2.item_code = t1.item_code
14 and t2.is_delete = 0
15 ) current_item
16 from
17 tab3 t1
18 where
19 t1.unique_id between 1 and 10000
20 and t1.is_delete = 0
21* and t1.status_code = '00'

10000行が選択されました。

経過: 00:00:03.81

実行計画
----------------------------------------------------------
Plan hash value: 2957188266

----------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 9998 | 253K| 424 (0)| 00:00:06 |
| 1 | SORT AGGREGATE | | 1 | 47 | | |
| 2 | NESTED LOOPS | | 2 | 94 | 5 (0)| 00:00:01 |
|* 3 | INDEX RANGE SCAN | TAB31_DEMO_IX | 1 | 29 | 3 (0)| 00:00:01 |
|* 4 | INDEX RANGE SCAN | TAB311_DEMO_IX | 2 | 36 | 2 (0)| 00:00:01 |
|* 5 | TABLE ACCESS BY INDEX ROWID| TAB3 | 9998 | 253K| 424 (0)| 00:00:06 |
|* 6 | INDEX RANGE SCAN | TAB3_PK | 10000 | | 23 (0)| 00:00:01 |
----------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

3 - access("T2"."ITEM_CODE"=:B1 AND "T2"."IS_DELETE"=0)
4 - access("T3"."SUB_ITEM_CODE"="T2"."SUB_ITEM_CODE" AND "T3"."IS_DELETE"=0)
5 - filter("T1"."IS_DELETE"=0 AND "T1"."STATUS_CODE"='00')
6 - access("T1"."UNIQUE_ID">=1 AND "T1"."UNIQUE_ID"<=10000)


統計
----------------------------------------------------------
1 recursive calls
0 db block gets
32839 consistent gets
4655 physical reads
0 redo size
326816 bytes sent via SQL*Net to client
7742 bytes received via SQL*Net from client
668 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
10000 rows processed

SCOTT>
SCOTT> @drop_demo5_ix
drop index tab31_demo_ix;

索引が削除されました。

経過: 00:00:00.42
drop index tab311_demo_ix;

索引が削除されました。

DEMO : NULLとハサミは使いよう。(Index Only Accessがその効果を失う日?!)

※セッション中のデモ時間短縮のため”暴走するスカラー副問合せ”のチューニング後の状態を同一条件の別テーブルで再現してあります。

Index Only Accessでチューニングしたはずの、スカラー副問合せが...再び暴れだした。どゆこと?
処理時間も以前より遅くなってるし、かつ特定の部分のROWSが異常に増加していて、Buffer Getsがすごい事になってます。


Index Only Accessのための索引を作ったものの
SCOTT> @demo5_2_ix
create index tab31_bk_demo_ix on tab31_bk(item_code, is_delete, sub_item_code) nologging;

索引が作成されました。

経過: 00:00:01.25
create index tab311_bk_demo_ix on tab311_bk(sub_item_code, is_delete, unique_id) nologging;

索引が作成されました。

SCOTT> @demo5_2
alter system flush buffer_cache;

システムが変更されました。

経過: 00:00:00.09
1 select
2 t1.unique_id,
3 t1.item_code,
4 (
5 select
6 max(t3.unique_id)
7 from
8 tab31_bk t2 join tab311_bk t3
9 on
10 t3.sub_item_code = t2.sub_item_code
11 and t3.is_delete = 0
12 where
13 t2.item_code = t1.item_code
14 and t2.is_delete = 0
15 ) current_item
16 from
17 tab3 t1
18 where
19 t1.unique_id between 1 and 10000
20 and t1.is_delete = 0
21* and t1.status_code = '00'

10000行が選択されました。

経過: 00:00:34.59

実行計画
----------------------------------------------------------
Plan hash value: 3069420010

-------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 9998 | 253K| 424 (0)| 00:00:06 |
| 1 | SORT AGGREGATE | | 1 | 47 | | |
| 2 | NESTED LOOPS | | 35974 | 1651K| 5 (0)| 00:00:01 |
|* 3 | INDEX RANGE SCAN | TAB31_BK_DEMO_IX | 1 | 29 | 3 (0)| 00:00:01 |
|* 4 | INDEX RANGE SCAN | TAB311_BK_DEMO_IX | 35978 | 632K| 2 (0)| 00:00:01 |
|* 5 | TABLE ACCESS BY INDEX ROWID| TAB3 | 9998 | 253K| 424 (0)| 00:00:06 |
|* 6 | INDEX RANGE SCAN | TAB3_PK | 10000 | | 23 (0)| 00:00:01 |
-------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

3 - access("T2"."ITEM_CODE"=:B1 AND "T2"."IS_DELETE"=0)
4 - access("T3"."SUB_ITEM_CODE"="T2"."SUB_ITEM_CODE" AND "T3"."IS_DELETE"=0)
5 - filter("T1"."IS_DELETE"=0 AND "T1"."STATUS_CODE"='00')
6 - access("T1"."UNIQUE_ID">=1 AND "T1"."UNIQUE_ID"<=10000)


統計
----------------------------------------------------------
1 recursive calls
0 db block gets
896697 consistent gets
5190 physical reads
0 redo size
326829 bytes sent via SQL*Net to client
7742 bytes received via SQL*Net from client
668 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
10000 rows processed

SCOTT>

DEMO : NULLとハサミは使いよう。(Index Only Accessがその効果を失う日?!)

なぜ、Index Only Accessが効果を失ってしまったのか。。。
スカラー副問合せのチューニングでは、Index Range ScanやIndex Unique ScanをNested Loop結合かつIndex Only Access化したのだが、
特定の値に大きな偏りがあり、広範囲のIndex Range ScanがNested Loop結合で繰り返されたのがその理由。

特定の値の意味を調査していくと、実はNULLでも問題ないという意味合いしかないことが発覚。

しか〜〜〜し、大人の事情で、該当列をNULLに更新してしまうことは許されない。さて、どのように対処するか!

閃いた!。 Oracle11g で登場した新機能を使え! (恐る恐るw でも事前にKROWNなど調べまくりましたよv)

特定の値をNULLに置換する仮想列を追加して、その列でIndex Only Accesssを実現する索引を作る。さらに、SQL文の結合条件だけは変更してもらう。
(影響範囲を最小にした対処だと思います. 仮想列が無かったら大変だったと思います)

以下の結果の通り、処理時間も以前チューニングした時間まで改善し、広範囲のIndex Range Scanも消えていることが実行計画からも確認できます。めでたしめでたし。

SCOTT> @demo5_2_virtual
alter
table tab311_bk add (sub_item_code_virtual CHAR(10) as (replace(sub_item_code,' ',null)) virtual);

表が変更されました。

経過: 00:00:00.57

SCOTT> @demo5_2_ix_2
create index tab311_bk_demo_vix on tab311_bk(sub_item_code_virtual, is_delete, unique_id) nologging;

索引が作成されました。

経過: 00:00:05.38

SCOTT> @demo5_2_2
alter system flush buffer_cache;

システムが変更されました。

経過: 00:00:00.07
1 select
2 t1.unique_id,
3 t1.item_code,
4 (
5 select
6 max(t3.unique_id)
7 from
8 tab31_bk t2 join tab311_bk t3
9 on
10 t3.sub_item_code_virtual = t2.sub_item_code
11 and t3.is_delete = 0
12 where
13 t2.item_code = t1.item_code
14 and t2.is_delete = 0
15 ) current_item
16 from
17 tab3 t1
18 where
19 t1.unique_id between 1 and 10000
20 and t1.is_delete = 0
21* and t1.status_code = '00'

10000行が選択されました。

経過: 00:00:03.45

実行計画
----------------------------------------------------------
Plan hash value: 2681694377

--------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 9998 | 253K| 424 (0)| 00:00:06 |
| 1 | SORT AGGREGATE | | 1 | 48 | | |
| 2 | NESTED LOOPS | | 7 | 336 | 5 (0)| 00:00:01 |
|* 3 | INDEX RANGE SCAN | TAB31_BK_DEMO_IX | 1 | 29 | 3 (0)| 00:00:01 |
|* 4 | INDEX RANGE SCAN | TAB311_BK_DEMO_VIX | 7 | 133 | 2 (0)| 00:00:01 |
|* 5 | TABLE ACCESS BY INDEX ROWID| TAB3 | 9998 | 253K| 424 (0)| 00:00:06 |
|* 6 | INDEX RANGE SCAN | TAB3_PK | 10000 | | 23 (0)| 00:00:01 |
--------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

3 - access("T2"."ITEM_CODE"=:B1 AND "T2"."IS_DELETE"=0)
4 - access("T3"."SUB_ITEM_CODE_VIRTUAL"="T2"."SUB_ITEM_CODE" AND "T3"."IS_DELETE"=0)
5 - filter("T1"."IS_DELETE"=0 AND "T1"."STATUS_CODE"='00')
6 - access("T1"."UNIQUE_ID">=1 AND "T1"."UNIQUE_ID"<=10000)


統計
----------------------------------------------------------
22 recursive calls
0 db block gets
32843 consistent gets
4072 physical reads
0 redo size
322687 bytes sent via SQL*Net to client
7742 bytes received via SQL*Net from client
668 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
10000 rows processed

SCOTT>
SCOTT> @drop_demo5_2_ix_2
drop index tab311_bk_demo_vix;

索引が削除されました。

経過: 00:00:00.29
SCOTT> @drop_demo5_2_ix
drop index tab31_bk_demo_ix;

索引が削除されました。

経過: 00:00:00.37
drop index tab311_bk_demo_ix;

索引が削除されました。

経過: 00:00:00.05

SCOTT> @drop_demo5_2_virtual
alter table tab311_bk drop (sub_item_code_virtual);

表が変更されました。

経過: 00:00:00.48

| | | コメント (0) | トラックバック (0)

2012年6月 2日 (土)

2012年7月21日(土)


| | | コメント (0) | トラックバック (0)

2012年2月25日 (土)

Oracle OpenWorld Tokyo 2012 Unconference


JPOUGのFacebookページはこちら :)


Unconference_jpoug


Oracle OpenWorldの3日目(4/6)に・・・・


なにかが・・・・・・


| | | コメント (0) | トラックバック (0)

2011年11月 1日 (火)

鬼熱かった! :: Insight out 2011- DB tech showcase

書くのおそくなっちゃいました m(_ _)m

10月19日〜21日に開催されたInsight out 2011- DB tech showcase
に、つまみ食いながらなんとか参加し、インサイトテクノロジーさんの鬼熱い魂を感じてきた :)

無理矢理空き時間作って参加したセッションは以下の通り。

  • Deep Dive into Oracle Database Patch (Oracle) - 諸橋渉
  • Why Why is probably the right answer (Oracle) - Tom Kyte
  • Rac Buffer Sharingの仕組み (Oracle) - 山下正
  • Effective Indexing (Oracle) - Tom Kyte
  • New challenges Information security technologies are facing (others) - David Maman
  • Developer and Indexes (Oracle) - Anjo Kolk

MySQLとかPostgreSQLとかOSSなのはOSCとかでも聴けるかなーと思いきづいたらOracle中心だったw

Effective Indexing/Developer and Indexes というセッションは予想以上だった、Indexを理解してるのって重要だよなーと改めて感じたセッションだった。

Tom Kyteさんが紹介していた書籍、「Relational Database Index Design and the Optimizers」


鬼熱い語りの山下さんのセッション、前回のOOWのUnconferenceの続編か?と思わせるような諸橋さんのセッション、つい引き込まれちゃいましたよ:)

参加者やスピーカが鬼熱いエンジニアであることは間違いないが、何と言っても、世界中からデータベースに関わる凄い方々を集めてしまうインサイトテクノロジーさんが一番、鬼熱いんじゃないかと感じた3日間だった。

来年も開催して頂きたいイベントだ。


Img_2299


| | | コメント (0) | トラックバック (0)

2009年9月 5日 (土)

随分前のイベントですが...「twitterの中の人と語る会」(6/30)@原宿

随分前のイベントですがアップし忘れていたので。 m(_ _)m 「twitterの中の人と語る会@原宿

イベント会場に着いたらPokenの中の人もいて、イベントはいつのまにか始まっていたww。twitterは随分前からアカウントを取っていたが本格的に使い始めたのはPokenがキッカケだろうな。個人的には。

Img_0652_3

Img_0654_2

Img_0657

Img_0660_2

| | | コメント (0) | トラックバック (0)

2009年5月15日 (金)

セキュリティEXPOに行って来た。

セキュリティEXPOへ行って来た。
しかも、Pokenももらった。:)

セキュリティExpoとは言っているけど、xxExpoのごった煮状態でIT関連で東京ビッグサイトをあれだけ広く使ったイベントも久々に見たかも。幕張メッセのMac World Expo Tokyoを思い出したよ。w
とそんな話は置いといて、少ない時間でいろいろ歩いたけどAntiVirusソフトはいろいろあるのね。ずっとSymantec使っていたからNo Checkだったよ。。。
で気になったのがGDATAPanda SecurityPokenの抽選もあったし)。GDATAなんかSpaten Beer飲めたのかな? 車だったからスルーしてたけど。。。

Panda securityのGate Defender PerfomaってSun Microsystemsのマシン使っているみたいだけど、近いうちにOracleのロゴになっちゃうのかなぁ?


Img_0457

Img_0459

Img_0461_2 Img_0466

| | | コメント (0) | トラックバック (0)

2009年4月23日 (木)

Javaじゃないよ、Brazil + Ethiopia + Guatemalaのブレンドだよ

Espressoでコーヒーブレイク中!。
今日はOracle Open World Tokyo 2009へ行く予定はないが、明日は午後から夕方まで参加予定。
犬好きの私の目的はWendyとのハイフォー。:)


ということでPoken準備完了。 Do you poken? wendy!

8

10



2009/4/24追記
そういえば、PokenのサイトってMySQL/GlassFish/Java使っているんだね。

バックナンバー
Oracle Open World Tokyo 2009 #1

| | | コメント (2) | トラックバック (1)

2008年2月 3日 (日)

iKnow user's partyに行ってきた。

iKnow User's Partyに参加してきた。

1次会ではなんとCerego Japanのケネスさんとカークさん?(間違ってない?)が・・・・・、いろいろな話は聞けたのだが、私の英会話スキルが貧弱すぎて・・・・・技術関連書籍の英語は読めても会話についていけない自分に改めて気付く..。

がんばらねば・・・

お酒も回ってきたのこれ以上は書けない・・・つづきはまた明日にでも...

と思ってiKnowにログインしてみたら megawattさんが日記にアップしていた。脱帽。。。

iKnow user's party dialy - by megawatt

iKnow user's party - Flickr Photos by megawatt

| | | コメント (0) | トラックバック (0)