« Apple Loopとチョップだけで頑張るGarageBand DTM 全部俺 Advent Calendar 2024 #12 - ネコだけにScratch追加したい その2 | トップページ | Apple Loopとチョップだけで頑張るGarageBand DTM 全部俺 Advent Calendar 2024 #14 - ネコだけにScratch追加したい その3の修正 »

2024年12月13日 (金) / Author : Hiroshi Sekiguchi.

実行計画は, SQL文のレントゲン写真だ! No.65 / JPOUG Advent Calendar 2024 / JSON-Relational Duality Views

本エントリーは、13日の金曜日のエントリーです。
昨日のポストは、Takayuki Nishio (Nisshii0)さんの「[Oracle] ここが違うよ Autonomous Database! 初めてデータ移行して気づいたこと」でした。




ということで、私のターン。

皆様の期待通り?、13日の金曜日なので、JSON を取り上げておきたいと思います。(実は元々別のながーーーいネタを用意していたのですが、13日の金曜日であることに気づきwww 以下略)
Oracle Database のJSON関連機能について、すでに多くの方がブログ等で書かれていることもあり、本エントリーでは、Mac De Oracleっぽくw、実行計画という名のレントゲン写真はどうなのかw を診ておきたいと思います。


Stable Diffusion WebUI
20241206-131544

対象とするのは、JSON-Relational Duality Views です。
この機能、名前の通り、リレーショナル表のままで、JSONにマッピングするVIEWを通して使えるようにしたものでOracle Database 23aiの新機能の一つです。(雑に解説すると。。)

気になりますよね。JSON-Relational Duality Viewsを介してアクセスした場合の実行計画!!!!

ちょっとわき道に逸れるのですが、Oracle Databaseには、RDFView という機能があります。リレーショナル表のままで、RDF Graphのトリプルとして参照する機能ですよね。これまた雑に解説すると。

実行計画は,SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 おまけ#3
トリプルとして扱うために、対象の列毎にSELECT文を作る必要がありかつ3列なのでUNIONも必要で、という想像通りのなかなかのレントゲン写真(実行計画でした)。
Rdfview


果たして、JSON-Relational Duality Views ではどうなるのか。。。。

早速、試してみましょう。

23aiを利用しています。

COTT@localhost:1521/freepdb1> select banner_full from v$version;

BANNER_FULL
--------------------------------------------------------------------------------
Oracle Database 23ai Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free
Version 23.4.0.24.05


まず、JSON-Relational Duality ViewsはViewなので元になるリレーショナル表を決めちゃいます。dept表をもとにして department表を作って使いましょう。 dept表のままでも良いのですけどもw

SCOTT@localhost:1521/freepdb1> set linesize 80
SCOTT@localhost:1521/freepdb1> desc dept
Name Null? Type
----------------------------------------- -------- ----------------------------
DEPTNO NOT NULL NUMBER(2)
DNAME VARCHAR2(14)
LOC VARCHAR2(13)

SCOTT@localhost:1521/freepdb1> select * from dept;

DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON

SCOTT@localhost:1521/freepdb1> create table department as select * from dept;

Table created.

SCOTT@localhost:1521/freepdb1> alter table department add constraint pk_department primary key (deptno) using index;

Table altered.


department表の列をJSONのキーにマップしちゃうだけ(おまけで, UPDATE/INSERT/DELETEも許可していますが、今回はSELECTしかしませんw)
JSON RELATIONAL DUALITY VIEWを作成します。(見ると リレーショナル表の列とJSONのキーをマップしているだけですね。シンプル)

SCOTT@localhost:1521/freepdb1> l
1 CREATE JSON RELATIONAL DUALITY VIEW department_dv
2 AS
3 SELECT
4 JSON { '_id' : d.deptno,
5 'departmentName' : d.dname,
6 'location' : d.loc }
7 FROM
8 department d
9* WITH UPDATE INSERT DELETE
SCOTT@localhost:1521/freepdb1> /

View created.

SCOTT@localhost:1521/freepdb1> select collection_name,collection_type from user_json_collections;

COLLECTION_NAME COLLECTION_T
------------------------------ ------------
DEPARTMENT_DV DUALITY VIEW

SCOTT@localhost:1521/freepdb1> set linesize 400
COTT@localhost:1521/freepdb1> select * from user_json_duality_views;

VIEW_NAME JSON ROOT_TABLE_NAME ROOT_TABLE_OWNER ALLOW_INSER ALLOW_UPDAT ALLOW_DELET READ_ONLY JSON_SCHEMA STATUS
------------------------------ ---- ------------------------------ ------------------------------ ----------- ----------- ----------- ----------- ------------------------------ -------
DEPARTMENT_DV DATA DEPARTMENT SCOTT TRUE TRUE TRUE FALSE {"title":"DEPARTMENT_DV","dbOb VALID
ject":"SCOTT.DEPARTMENT_DV","d
bObjectType":"dualit


特に何も指定せず問い合わせると、まんまのJSONが返されます。

SCOTT@localhost:1521/freepdb1> set long 4000
SCOTT@localhost:1521/freepdb1> set longchunk 4000
SCOTT@localhost:1521/freepdb1> set linesize 400
SCOTT@localhost:1521/freepdb1> select * from department_dv;

DATA
--------------------------------------------------------------------------------------------------------------------------------------------------
{"_id":10,"_metadata":{"etag":"66F269F721C734BAE74D56D6A948D0F6","asof":"0000000001799313"},"departmentName":"ACCOUNTING","location":"NEW YORK"}
{"_id":20,"_metadata":{"etag":"8A0701C115BFECAB64C34E2FF406FFDA","asof":"0000000001799313"},"departmentName":"RESEARCH","location":"DALLAS"}
{"_id":30,"_metadata":{"etag":"A7CDA588F9052B35B56E00BB22B6EC6F","asof":"0000000001799313"},"departmentName":"SALES","location":"CHICAGO"}
{"_id":40,"_metadata":{"etag":"93AE902896310C0DFFCE3FC70E0479F6","asof":"0000000001799313"},"departmentName":"OPERATIONS","location":"BOSTON"}


さて、table full scanになると思いますが、とりあえず見てみましょう。

SCOTT@localhost:1521/freepdb1> set autot trace exp stat
SCOTT@localhost:1521/freepdb1> select * from department_dv;

Elapsed: 00:00:00.03

Execution Plan
----------------------------------------------------------
Plan hash value: 826413278

--------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 4 | 80 | 3 (0)| 00:00:01 |
| 1 | TABLE ACCESS FULL| DEPARTMENT | 4 | 80 | 3 (0)| 00:00:01 |
--------------------------------------------------------------------------------

Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
2 consistent gets
0 physical reads
0 redo size
1469 bytes sent via SQL*Net to client
473 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
4 rows processed

SCOTT@localhost:1521/freepdb1> set autot off
SCOTT@localhost:1521/freepdb1> set linesize 80
SCOTT@localhost:1521/freepdb1> desc department_dv
Name Null? Type
----------------------------------------- -------- ----------------------------
DATA JSON

SCOTT@localhost:1521/freepdb1> set linesize 400
SCOTT@localhost:1521/freepdb1> col _id for a30
SCOTT@localhost:1521/freepdb1> col departmentName for a30
SCOTT@localhost:1521/freepdb1> col location for a30

...略...

リレーショナル表っぽいクエリーにもできます。

SCOTT@localhost:1521/freepdb1> r
1 select d.data."_id",
2 d.data."departmentName",
3 d.data."location"
4 from department_dv d
5* order by 1

_id departmentName location
------------------------------ ------------------------------ ------------------------------
10 "ACCOUNTING" "NEW YORK"
20 "RESEARCH" "DALLAS"
30 "SALES" "CHICAGO"
40 "OPERATIONS" "BOSTON"

では、次に、主キーにマップした _id 列でアクセスしてみましょう。おおおおお、普通に、INDEX UQNIQE SCANでしたね。(想像していた通りですがw)
Predicate Information に現れるアクセスパスを見ると、 access("D"."DEPTNO"=30) となっており、内部的にはリレーショナル表を問い合わせるSQL文に書き換えられているように見えますよね(まだ調べていないですがw)

SCOTT@localhost:1521/freepdb1> set autot trace exp stat
SCOTT@localhost:1521/freepdb1> select json_serialize(d.data pretty) from department_dv d where d.data."_id" = 30;

Elapsed: 00:00:00.01

Execution Plan
----------------------------------------------------------
Plan hash value: 3132674683

---------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 20 | 1 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| DEPARTMENT | 1 | 20 | 1 (0)| 00:00:01 |
|* 2 | INDEX UNIQUE SCAN | PK_DEPARTMENT | 1 | | 0 (0)| 00:00:01 |
---------------------------------------------------------------------------------------------

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

2 - access("D"."DEPTNO"=30)


Statistics
----------------------------------------------------------
8 recursive calls
0 db block gets
5 consistent gets
0 physical reads
0 redo size
782 bytes sent via SQL*Net to client
108 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed

SCOTT@localhost:1521/freepdb1> set autot off
SCOTT@localhost:1521/freepdb1> r
1* select json_serialize(d.data pretty) from department_dv d where d.data."location" = 'CHICAGO'

JSON_SERIALIZE(D.DATAPRETTY)
----------------------------------------------------------------------------------------------------
{
"_id" : 30,
"_metadata" :
{
"etag" : "A7CDA588F9052B35B56E00BB22B6EC6F",
"asof" : "0000000001799BF8"
},
"departmentName" : "SALES",
"location" : "CHICAGO"
}

...略...

SCOTT@localhost:1521/freepdb1> r
1 select
2 d.data."_id" as deptno
3 , d.data."departmentName" as department_name
4 , d.data."location" as location
5 from
6 department_dv d
7 where
8* d.data."location" = 'CHICAGO'

DEPTNO DEPARTMENT_NAME LOCATION
------------------------------ ------------------------------ ------------------------------
30 "SALES" "CHICAGO"


JSON-Relational Duality Viewsから問い合わせてもリレーショナル表を直接問い合わせるのと同じなんですねぇ。なんとなく安心w

13日の金曜日のJSONネタなので、恐ろしーい結果を期待していた方、ごめんなさいwwww JSON怖くないですw


明日のJPOUG Advent Calendar 2024は、ketsujiさんです。




Related article 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
・実行計画は, SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 - Day 25 / UNION ALL (RECURSIVE WITH) DEPTH FIRST, RECURSIVE WITH PUMP
・実行計画は, SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 - おまけ#1 / STAR TRANSFORM, VECTOR TRANSFORM (DWH向け)
・実行計画は, SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 - おまけ#2 / MERGE (UPSERT)
・実行計画は, SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 - おまけ#3 / RDFView
・実行計画は, SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 - おまけ#4 / INDEX FULL SCAN (MIN/MAX) - Index Only Scan
・実行計画は, SQL文のレントゲン写真だ! No.30 - LOAD TABLE CONVENTIONAL vs. LOAD AS SELECT
・実行計画は, SQL文のレントゲン写真だ! No.31 - TEMP TABLE TRANSFORMATION LOAD AS SELECT (CURSOR DURATION MEMORY)
・実行計画は, SQL文のレントゲン写真だ! No.32 - EXTERNAL TABLE ACCESS FULL / INMEMORY FULL
・実行計画は, SQL文のレントゲン写真だ! No.33 - BITMAP CONVERSION TO ROWIDS
・実行計画は, SQL文のレントゲン写真だ! No.34 - 似て非なるもの USE_CONCAT と OR_EXPAND ヒント と 手書きSQLのレントゲンの見分け方
・実行計画は, SQL文のレントゲン写真だ! No.35 - 似て非なるもの USE_CONCAT と OR_EXPANDヒントとパラレルクエリー
・実行計画は, SQL文のレントゲン写真だ! Oracle Database (全部俺)Advent Calendar 2022 Day 1 / No.36 / INTERSECT ALL
・実行計画は, SQL文のレントゲン写真だ! Oracle Database (全部俺)Advent Calendar 2022 Day 2 / No.37 / MINUS ALL
・実行計画は, SQL文のレントゲン写真だ! Oracle Database (全部俺)Advent Calendar 2022 Day 3 / No.38 / EXCEPT and EXCEPT ALL
・実行計画は, SQL文のレントゲン写真だ! Oracle Database (全部俺)Advent Calendar 2022 Day 4 / No.39 / In-Memory Hybrid Scans
・実行計画は, SQL文のレントゲン写真だ! Oracle Database (全部俺)Advent Calendar 2022 Day 5 / No.40 / PIVOT and UNPIVOT
・実行計画は, SQL文のレントゲン写真だ! Oracle Database (全部俺)Advent Calendar 2022 Day 6 / No.41 / In-Memory Vectorized Join
・実行計画は, SQL文のレントゲン写真だ! Oracle Database (全部俺)Advent Calendar 2022 Day 7 / No.42 / INDEX RANGE SCAN (MULTI VALUE)
・実行計画は, SQL文のレントゲン写真だ! Oracle Database (全部俺)Advent Calendar 2022 Day 8 / No.43 / TABLE ACCESS BY INDEX ROWID BATCHED
・実行計画は, SQL文のレントゲン写真だ! Oracle Database (全部俺)Advent Calendar 2022 Day 9 / No.44 / COLLECTION ITERATOR PICKLER FETCH
・実行計画は, SQL文のレントゲン写真だ! Oracle Database (全部俺)Advent Calendar 2022 Day 10 / No.45 / MAT_VIEW REWRITE ACCESS FULL
・実行計画は, SQL文のレントゲン写真だ! Oracle Database (全部俺)Advent Calendar 2022 Day 11 / No.46 / GROUPING SETS, ROLLUP, CUBE
・実行計画は, SQL文のレントゲン写真だ! Oracle Database (全部俺)Advent Calendar 2022 Day 12 / No.47 / TEMP TABLE TRANSFORMATION
・実行計画は, SQL文のレントゲン写真だ! Oracle Database (全部俺)Advent Calendar 2022 Day 13 / No.48 / MULTI-TABLE INSERT
・実行計画は, SQL文のレントゲン写真だ! Oracle Database (全部俺)Advent Calendar 2022 Day 14 / No.49 / the DUAL Table
・実行計画は, SQL文のレントゲン写真だ! Oracle Database (全部俺)Advent Calendar 2022 Day 15 / No.50 / REMOTE
・実行計画は, SQL文のレントゲン写真だ! Oracle Database (全部俺)Advent Calendar 2022 Day 16 / No.51 / Concurrent Execution of Union All and Union
・実行計画は, SQL文のレントゲン写真だ! Oracle Database (全部俺)Advent Calendar 2022 Day 17 / No.52 / Order by Elimination
・実行計画は, SQL文のレントゲン写真だ! Oracle Database (全部俺)Advent Calendar 2022 Day 18 / No.53 / Join Elimination
・実行計画は, SQL文のレントゲン写真だ! Oracle Database (全部俺)Advent Calendar 2022 Day 19 / No.54 / Group by Elimination
・実行計画は, SQL文のレントゲン写真だ! Oracle Database (全部俺)Advent Calendar 2022 Day 20 / No.55 / DISTINCT Elimination
・実行計画は, SQL文のレントゲン写真だ! Oracle Database (全部俺)Advent Calendar 2022 Day 21 / No.56 / INLIST ITERATOR と Sub Query と STATISTICS COLLECTOR
・実行計画は, SQL文のレントゲン写真だ! Oracle Database (全部俺)Advent Calendar 2022 Day 22 / No.57 / Subquery Unnesting
・実行計画は, SQL文のレントゲン写真だ! Oracle Database (全部俺)Advent Calendar 2022 Day 23 / No.58 / ANTI JOIN
・実行計画は, SQL文のレントゲン写真だ! Oracle Database (全部俺)Advent Calendar 2022 Day 24 / No.59 / SQL MACRO (19.7〜)
・実行計画は, SQL文のレントゲン写真だ! Oracle Database (全部俺)Advent Calendar 2022 Day 25 / No.60 / ANSI JOIN
・実行計画は, SQL文のレントゲン写真だ! Oracle Database (全部俺)Advent Calendar 2022 / No.60 / ANSI JOINのおまけ
実行計画は, SQL文のレントゲン写真だ! Oracle Database (全部俺)Advent Calendar 2022 / No.61 / ANSI JOINのおまけのおまけ
実行計画は, SQL文のレントゲン写真だ! No.62 / ORDBMS機能であるコレクション型の列をアクセスする実行計画ってどうなるの?
実行計画は, SQL文のレントゲン写真だ! No.63 / Join Elimination (再び)その1
実行計画は, SQL文のレントゲン写真だ! No.63 / Join Elimination (再び)その2
実行計画は, SQL文のレントゲン写真だ! No.63 / Join Elimination (再び)その3
実行計画は, SQL文のレントゲン写真だ! No.64 / 先生、私のLEFT OUTER JOINが無いんです!!(Join Elimination番外編

| |

コメント

コメントを書く