2020年2月23日 (日)

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

2020年も2ヶ月が終わるところ, かつ, 新型コロナウィルスの影響をいろいろ受けつつ今後どうなるんだろうと, 週末は外出を最小限に入手困難なマスクの消費を抑える意味もあり必要最小限の外出にする作戦....
とはいえ, ネットでググると, 消毒用アルコール詰め替え4Lやマスクが, 想像の斜め上をいく値段で売られてて, なんなのだろうなんて...

余談はこれぐらいにして, 2019年のくれのネタのおまけの追加でございます.


Index Only Scanを利用したmin()/max()で性能チューニングという、比較的レアな治療をしたことのある方なら見覚えのあるレントゲン写真(実行計画)だと思います. (たまたまそうなってたということもありますが, これを狙ったチューニング方法もあります)

当然ですが、Index Only Scanを狙う場面は, 行長が長いがSELECT文では索引にできそうな(しても悪影響なさそうな)一部の列しか利用していない. ほぼ全ての列がSELECT文中で利用されているような場合にはIndex Only Scanは不向きなのはみなさんご存知の通りです.

なつかしいエントリですが, 以下エントリーのスライド(SlideShare使ってなかった頃なので, KeynoteをHTMLへ変換)を参照のこと.
いん!、イン!、Index どっぷり Inde Only Access生活w - Oracle OpenWorld Unconference presented by JPOUG

上記エントリーのスライドでも紹介していますが, MIN()/MAX()関数が利用されており, Index Only Scanが有効なケース(アクセスするブロック数が多くOLTPの性能が性能要件を満たせないようなケース. 大抵の場合、物理IOの影響か, キャッシュにヒットしてもBuffer読み込みが多すぎる、かつ、同時セッション数が多いような場合にはいろいろな改善効果が見込めます)で威力を発揮します.

例えば, db sequential read, read by other session, etc....の削減効果, キャッシュヒット率が高い場合で DB CPUは高いけど実は無駄に高いだけ〜な状況という名の内臓脂肪多くて隠れ肥満なシステムは, 物理IOが少なくてCPU利用率が高い事も多く, リソースうまく使い切ってますねー, スケールアップするしかなさそうですねーと誤診されるケースもあったりw
しっかり診察する必要はありますが, 治療できる可能性がある場合には, Buffer Getsを削減するためIndex Only Scanを利用したチューニングという名の治療(当然副作用を伴います. その点には注意が必要です)を続けることで大きく改善させた例もあります. 実際にそんなことをやってたこともありました.

Statisticsをみるとお判りだと思いますが, Id=2でINDEX FULL SCANとは出ていますが, physical readsが1回, 1blockのアクセスになっている点がポイントです.
Indexonlyscan_min_max

続きを読む "実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 おまけ#4"

| | コメント (0)

FAQ / SCOTTスキーマにあるEMP表とかどうすれば作れるの?

SCOTTスキーマをアンロックしたはいいけど、サンプル表がないーーーいなんてときは、utlsampl.sql を実行すればいいよ

続きを読む "FAQ / SCOTTスキーマにあるEMP表とかどうすれば作れるの? "

| | コメント (0)

2020年1月20日 (月)

W3C Translations of Current W3C Technical Reports

ブックマーク代わりのメモ

Translations of Current W3C Technical Reports


not already a completed or ongoing translation for the technical report in the language.

| | コメント (0)

2020年1月 6日 (月)

How to fix when can't boot VM - VirtualBox error : Trying to open a VM config ".... .vbox" which has the same UUID as an existing virtual machine / FAQ

なにがどうしてなのか、まったくわかりませんが、VirtualBoXのVMが突然アクセスできなくなり以下のような状況になった。
理由は不明ですが、似たような症状の方は意外に多いようですが、解決方法がわかりやすくまとまってるエントリーもなさそうだったので、対処した手順を備忘録として書いておきます。

先日まで問題なく使えてなのですが、なにかのはずみでこうなっちゃうこともあるらしい。まさにその状態だったのがこれ。
Vbox000

どのようなエラーなのかも不明だったのですが、.vboxファイルと.vmdkそして、Snapshotsの場所を確認...

$ cd /Volumes/Macintosh\ HD/VirtualBoxDisks/test 
$ ll
-rw------- 1 hoge foobar 21147287552 1 4 18:26 test-disk1.vmdk
-rw-------@ 1 hoge foobar 16163 11 14 2017 test.vbox
-rw------- 1 hoge foobar 16163 11 14 2017 test.vbox-prev
drwx------ 6 hoge foobar 192 11 14 2017 Logs
drwx------ 4 hoge foobar 128 11 11 2017 Snapshots

続きを読む "How to fix when can't boot VM - VirtualBox error : Trying to open a VM config ".... .vbox" which has the same UUID as an existing virtual machine / FAQ"

| | コメント (0)

2019年12月31日 (火)

Mac De Oracle - 気づいたら15年たってた / メモ

カーグラフィックTV(おじさんたちしか見ないだろうけどw)って結構振り返りネタしてるので、Mac De Oracleもたまにはそんなネタを。

ところで、このブログのタイトルですが、当時Mac de Zope(後にCube de Zopeに改名)というPythonというかZopeネタ扱っていたサイトがお気に入りで、その名称などにインスパイアされたのが、このMac De Oracle。
http://discus-hamburg.cocolog-nifty.com/mac_de_oracle/2007/08/post_5133.html

Mac De Oracle season 1 episode 1! 記念すべき第一回話w うちの奥さんからBlog楽しいよー、書いてみなよーと、そそのかされたのが運の尽きw (嘘
2005/5/24 - Panther De Oracle10g その1

Cube G4からPowerMac G5になったので、season 2 かだよな〜。OracleからGeneric ConnectivityでPostgreSQL、MySQLそして、FirebirdとかDB Linkでぜーんぶ繋いでた。仕事でしらべてたとはいえ、いろいろ熱いなw
2005/12/31 - Mac De Oracle Heterogeneous! #3

2006年ぐらいからRACも避けて通れなくなりつつあり、資金のない中とうやってお勉強しましょうかということになるわけです。はい。OTN Professional というやつがあって、それを十二分に活用してたのがこと時期かな〜
まだリアルな環境ですね。
2006/12/30 - Mac De Oracle - 10万円 de RAC #2

実はこのころから開発片手に、チューニング案件が多くなってきました。ネタにもしてましたが、このころ多かったのが Rule Base OptimizerからCost base Optimizerに切り替わってCost Baseなにそれ、バインドピークなにそれー
みたいなところからシステムテストやら負荷テスト時期になる、あちこちで、火の手が上がる。みたいな時期でしたーw

バインド変数を全く使ってないシステムで、結合テストで負荷試験したらCPUリソース枯渇 - HPのデカイサーバーがw - バインド変数使えよ案件 とか

32bitのWindowsでメモリ不足が様々な問題を引き起こしてた、それにバインド変数つかってねーし、ORA-12518連発 - バインド変数使えよ、階層問合使えよ、32bitのメモリ空間のサイズ考えてねー 案件 とか

火消しでいろいろ呼ばれましたーw

という、今ではあまりお目にかからなくなってきたチューニングの数々ですが、これ以降SQLチューニング案件に関わることが多くなっていきますw が、子供がうまれて、それどころじゃない、という感じにもなったのがこのころですねw 保育園待機児童問題に気づいたのもこのころでした。
2007/12/31 - よいお年を! 2008/12/28 - よいお年を! 2009/12/31 - よいお年を!

子育てでドタバタしている間にも、世の中は変わっていきます、そして、VirtualBox de RAC というリアルな環境から仮想環境で Oracleと戯れ始めます。  
2010/12/31 - VirtualBox de Oracle11g R2 RAC #13

この年に、JPOUG (Japan Oracle User Group)がBootしました。そして、そのきっかけを作ったGuutaraと先日で飲んだばかりw。twitterやjjugとかGoogle Waveとかゆるーいつながりがすべての始まりでしたね〜。
2011/12/31 - よいお年を!

このころRACネタを封印、s4r_agentさんがRAC何ノード起動できるかシリーズをスタート。SQLチューニングでスクランブルしたり、DBおそーいと呼ばれていったら、javascript遅いだけーみたいな IEのjs遅い案件に巻き込まれることもおおかった年w でした。
2012/12/25 - Indexがあれば、いいってもんじゃない。中身がたいせつ

こんなネタもやってましたねー
2013/12/31 - SELECT ~ FOR UPDATE SKIP LOCKED その2

SQLチューニングキャラが確立されてきたこともあり、ネタ傾向が徐々に変わってきたような気がします。
2014/12/17 - 机上SQLチューニング、クイズ! 駆動表(外部表)はどれだ!!!!

細かいテクニックをおぼえるのに遊びながら覚えてたようなw
2015/12/30 - Pipelined table function で ascii art

昔のmacOSというかMacOSというか、Kanji Talkというか無駄なところにいろいろニッコリするような仕掛けがあってある意味余裕がある感じがしなくもないわけですが、最近のOS含め、そんなのあるのかなー。
2016/12/30 - 昔、Mac OSがやってようなことを... VirtualBox の GuestOS起動スプラッシュ

いろいろと悩み始めてた年ですw
2017/12/4 - ”utl_file I/O” - この症状はあれの可能性が高いですね。

そして, 移籍後、気持ちの余裕がなくてあまり書けてない年だったw
2018/11/25 - MacPro (mid2012)をmacOS Mojaveにアップデート / FAQ

気持ちの余裕は無いなりにw いろいろやってますw
2019/12/30 - 実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 おまけ#3

2019/12/31
そして、16年目へ
52700470

| | コメント (0)

2019年12月30日 (月)

実行計画は,SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 おまけ#3

この実行計画がなにを行っているか見抜けたかたは, 前日のエントリーを読んだか, RDFVIEWを利用したRDF Graphを試したことがある方ぐらいだと思います.
RDF Semantic Graph「RDF 超入門」

RDFトリプルをRelational表にマップしてダイレクトにアクセスする方式なのですが, ご存じない方には何のこっちゃというのも仕方ないと思います.
3,4年前ぐらいに, なんとなーく流れ的に関わることになって, 寝る暇も惜しんでRDFトリプルストア (実態はオブジェクト表だったはず. 違ったらコメント頂けますと幸いです) とこのRDFVIEWのSQLチューニング方法を調べていたもんですw

そのころは余裕なさすぎてブログにも書けずじまいでしたが, 良い機会なのでRDFVIEWを問い合わせた実行計画をレントゲン写真として載せておきます.
詳細は前日の準備段階のエントリーを読んでいただけると良いかと思いますが, 知らない用語とかいきなりでてきているので, なんとなーくそんなもんかなーぐらいの理解よいと思います.

RDFVIEWのを問い合わせるSQL文は, SEM_MATCH()を利用するのが特徴で, RDFVIEW最大の特徴であるRelational表を直接よみながら, 最終的に RDFトリプルを返すという点にあります.
R2RML: RDB to RDF Mapping Language / W3Cあたりを読んでもらうと想像できるのではないかと思います. 読んで最初にきづくのは,それに関わっているのは Oracle社の方だったりしてるので納得感があります.

ということで、
SQLは以下のとおり. 関わったことがない方はこれまた見たこともない SEM_MATCH()関数が大量のパラメータを取って呼び出されていることが見えるぐらいですね。
裏では, SEM_MODEL()で指定したRDF Graphのモデルに対応したRelational表のEMPLOYEES表からEMPLOYEE_IDを元に, FIRST_NAME, LAST_NAME, MANAGER_IDの3列を, それぞれをトリプルとして返すようなマッピングになっています.

SELECT
s
, p
, o
FROM
TABLE (
SEM_MATCH (
'{?s ?p ?o}'
, SEM_MODELS('TEST_MODEL1')
, null
, null
, null
, null
, ' '
, null
, null
, 'RDFUSER'
, 'LOCALNET'
)
)
ORDER BY
s
,p;
RDFUSER@orcl> desc employees
Name Null? Type
----------------------------------------- -------- ----------------------------
EMPLOYEE_ID NOT NULL NUMBER(6)
FIRST_NAME VARCHAR2(20)
LAST_NAME NOT NULL VARCHAR2(25)
EMAIL NOT NULL VARCHAR2(25)
PHONE_NUMBER VARCHAR2(20)
HIRE_DATE NOT NULL DATE
JOB_ID NOT NULL VARCHAR2(10)
SALARY NUMBER(8,2)
COMMISSION_PCT NUMBER(2,2)
MANAGER_ID NUMBER(6)
DEPARTMENT_ID NUMBER(4)

RDFUSER@orcl> break on index_name skip 1
RDFUSER@orcl> select index_name,column_name from user_ind_columns where table_name='EMPLOYEES' order by 1,2;

INDEX_NAME COLUMN_NAME
------------------------------ ------------------------------
EMP_DEPARTMENT_IX DEPARTMENT_ID

EMP_EMAIL_UK EMAIL

EMP_EMP_ID_PK EMPLOYEE_ID

EMP_JOB_IX JOB_ID

EMP_MANAGER_IX MANAGER_ID

EMP_NAME_IX FIRST_NAME
LAST_NAME

続きを読む "実行計画は,SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 おまけ#3"

| | コメント (0)

2019年12月29日 (日)

RDFナレッジ・グラフ / 備忘録 19c

5年ぐらい前に触ったことがある程度で、すっかり忘れてしまった。しばらくぶりで思い出してパタパタしてみたら、Apache Jenaも含めていろいろ変わっていたので備忘録

RDFナレッジ・グラフ開発者ガイド RDFナレッジ・グラフの概要

R2RML: RDB to RDF Mapping Language

A Direct Mapping of Relational Data to RDF

いろいろ思い出しながら....

$ sqlplus sys@orclcdb as sysdba

SQL*Plus: Release 19.0.0.0.0 - Production on Sat Dec 28 00:51:52 2019
Version 19.3.0.0.0

Copyright (c) 1982, 2019, Oracle. All rights reserved.

Enter password:

Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.3.0.0.0

SQL> col namespace for a30
SQL> col value for a40
SQL> col description for a50
SQL> set linesize 400
SQL> set tab off
SYS@orclcdb> select * from MDSYS.RDF_PARAMETER;

NAMESPACE ATTRIBUTE VALUE DESCRIPTION
------------------- ----------------- ------------- --------------------------------------------------
COMPONENT RDFCTX INSTALLED Semantic (Text) Search component
COMPONENT RDFOLS INSTALLED RDF Optional component for OLS support
MDSYS SEM_VERSION 19.1.0.0.0 VALID

SYS@orclcdb> r
1 SELECT namespace, attribute, value FROM mdsys.rdf_parameter
2 WHERE namespace='MDSYS'
3 AND attribute IN ('FLOAT_DOUBLE_DECIMAL',
4 'XSD_TIME', 'XSD_BOOLEAN',
5* 'DATA_CONVERSION_CHECK')

no rows selected

SYS@orclcdb> conn system@orcl
Enter password:
Connected.
SYSTEM@orcl> create tablespace rdf_users datafile 'rds_users01.dbf' size 128m reuse autoextend on next 64m maxsize unlimited segment space management auto;

Tablespace created.

SYSTEM@orcl> create user rdfuser identified by hogehoge default tablespace rdf_users temporary tablespace temp;

User created.

SYSTEM@orcl> grant create view to rdfuser;

Grant succeeded.

SYSTEM@orcl> grant unlimited tablespace to rdfuser;

Grant succeeded.

SYSTEM@orcl> grant unlimited tablespace to mdsys;

Grant succeeded.

SYSTEM@orcl> grant select any dictionary to rdfuser;

Grant succeeded.

SYSTEM@orcl> grant connect, resource to rdfuser;

Grant succeeded.

SYSTEM@orcl> execute sem_apis.create_sem_network('RDF_USERS', network_owner=>'RDFUSER', network_name=>'LOCALNET');

PL/SQL procedure successfully completed.


SYSTEM@orcl> conn rdfuser@orcl
Enter password:
Connected.
RDFUSER@orcl>

RDFUSER@orcl> l
1 create table r2rmlview_nt_staging_tab (
2 rdf$stc_sub varchar2(4000) not null
3 ,rdf$stc_pred varchar2(4000) not null
4 ,rdf$stc_obj varchar2(4000) not null
5 )
6* nologging
RDFUSER@orcl> /

Table created.

RDFUSER@orcl> l
1 create table rdfview_export_tab (
2 rdf$stc_sub varchar2(4000) not null
3 ,rdf$stc_pred varchar2(4000) not null
4 ,rdf$stc_obj varchar2(4000) not null
5 )
6* nologging
RDFUSER@orcl> /

Table created.

RDFでいろいろやるには sga_targetやsga_max_sizeはそれなりに必要なので適当に調整

そして、Apache Jenaのrdfcatもdeprecatedになってて、これまたしばし時代に追いつく作業を....

RDFUSER@orcl> !rdfcat --help
------------------------------------------------------------------
DEPRECATED: Please use 'riot' instead.
http://jena.apache.org/documentation/io/#command-line-tools
------------------------------------------------------------------

------------------------------------
DEPRECATED: Please use riot instead.
------------------------------------

Usage: java jena.rdfcat (option|input)*
Concatenates the contents of zero or more input RDF documents.
Options: -out N3 | N-TRIPLE | RDF/XML | RDF/XML-ABBREV
-n expect subsequent inputs in N3 syntax
-x expect subsequent inputs in RDF/XML syntax
-t expect subsequent inputs in N-TRIPLE syntax
-[no]include include rdfs:seeAlso and owl:imports
input can be filename, URL, or - for stdin
Recognised aliases for -n are: -n3 -ttl or -N3
Recognised aliases for -x are: -xml -rdf or -rdfxml
Recognised aliases for -t are: -ntriple
Output format aliases: x, xml or rdf for RDF/XML, n, n3 or ttl for N3, t or ntriple for N-TRIPLE
See the Javadoc for jena.rdfcat for additional details.

rdfcatに変えて、riot ってやつをつかわなきゃいけなくなったっぽい。

RDFUSER@orcl> !riot -version
Jena: VERSION: 3.13.1
Jena: BUILD_DATE: 2019-10-06T18:57:39+0000
RIOT: VERSION: 3.13.1
RIOT: BUILD_DATE: 2019-10-06T18:57:39+0000

ちなみに、SHユーザのEMPLOYEES表や索引をRDFUSERユーザへコピーした上で、以下のような、RDFVIEWとRelational表と列のマッピングをTurtle (Terse RDF Triple Language)で定義した。

RDFUSER@orcl> !cat test_real_rdf_r2rml.ttl
@prefix rr: .
@prefix xsd: .
@prefix ex: .

ex:TriplesMap_Employees
rr:logicalTable [ rr:tableName "EMPLOYEES" ];
rr:subjectMap [
rr:template "http://r2rml.com/employees/{EMPLOYEE_ID}";
rr:class ex:Employees;
];

rr:predicateObjectMap [
rr:predicate ex:FirstName;
rr:objectMap [ rr:column "FIRST_NAME" ];
];

rr:predicateObjectMap [
rr:predicate ex:LastName;
rr:objectMap [ rr:column "LAST_NAME" ];
];

rr:predicateObjectMap [
rr:predicate ex:ManagerId;
rr:objectMap [ rr:column "MANAGER_ID" ];
].

5年ぐらい前の記憶ではrdfcatを利用して変換していたが、今は、 riot というコマンドを利用してTurtle(Terse RDF Triple Language)N-Triplesへ変換するみたいね。

RDFUSER@orcl> !riot --out=N-TRIPLE test_real_rdf_r2rml.ttl > test_real_rdf_r2rml_use_riot.nt

RDFUSER@orcl> !cat test_real_rdf_r2rml_use_riot.nt
_:Bf70c7f0d1b418dc63ad89dbcea313cd1 "EMPLOYEES" .
_:Bf70c7f0d1b418dc63ad89dbcea313cd1 .
_:Bdd4cf5eb9ecb0b12212d342518513827 "http://r2rml.com/employees/{EMPLOYEE_ID}" .
_:Bdd4cf5eb9ecb0b12212d342518513827 .
_:Bdd4cf5eb9ecb0b12212d342518513827 .
_:B310abfde7d61aac8f303fbd1f4ba5db8 .
_:Bfe48b8372e4da59d0ce99e0e24b894ad "FIRST_NAME" .
_:B310abfde7d61aac8f303fbd1f4ba5db8 _:Bfe48b8372e4da59d0ce99e0e24b894ad .
_:B310abfde7d61aac8f303fbd1f4ba5db8 .
_:B11c76919901c01b44cb0e2507a997c28 .
_:B5474fc7a1b7c7302521175dac3c58028 "LAST_NAME" .
_:B11c76919901c01b44cb0e2507a997c28 _:B5474fc7a1b7c7302521175dac3c58028 .
_:B11c76919901c01b44cb0e2507a997c28 .
_:Be7008cecff6b130ea15b4ba060cee0fb .
_:B0f41936e13c4655082ee47f866dc9f61 "MANAGER_ID" .
_:Be7008cecff6b130ea15b4ba060cee0fb _:B0f41936e13c4655082ee47f866dc9f61 .
_:Be7008cecff6b130ea15b4ba060cee0fb .

続きを読む "RDFナレッジ・グラフ / 備忘録 19c"

| | コメント (0)

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

Id=1とId=2のMERGE STATEMENTMERGEですぐにわかるとおもいます. MERGE文(通称UPSERT)の実行計画というレントゲン写真w

merge into sample_table
using sample_table_temp
on (sample_table.id = sample_table_temp.id)
when matched then
update set
sample_table.data = sample_table_temp.data,
sample_table.update_timestamp = systimestamp
when not matched then
insert values
(
sample_table_temp.id,
sample_table_temp.data,
systimestamp,
null
);

Merge

続きを読む "実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 おまけ#2"

| | コメント (0)

2019年12月28日 (土)

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

ヒントで無理やりSQL transformationーーーん, してますが、DWH系、スタースキーマで利用する star transformationです.
ファクト表から各ディメンジョン表への参照整合性制約とビットマップ索引が必須となります. また, BITMAP MERGE/BITMAP CONVERSION TO ROWIDS/TABLE ACCESS BY USER ROWID (Id=33)にあるようにROWIDで1行1行アクセスする動きからも想像できると思いますが, ディメンジョン表のデータでファクト表が十分に絞り込めないケースでは性能的メリットはありません。ファクト表が絞り込めずに, 数億行を1行1行取得(シリアルに)していることを思い描ければどのようなケースが使いどころかも想像できるのではないでしょうか?
実行計画の特徴は, BITMAP MERGE/BITMAP CONVERSION TO ROWIDS というディメンジョン表のビットマップ索引を利用したアクセスと, ファクト表をなる表をBITMAP CONVERSION TO ROWIDSでえられるROWIDでアクセスしているとという点.
そして、Noteセクションにリストされる - star transformation used for this statement で判断できます.

SELECT
/*+
STAR_TRANSFORMATION
*/
ch.channel_class
, c.cust_city
, t.calendar_quarter_desc
, SUM(s.amount_sold) sales_amount
FROM
sales s
, times t
, customers c
, channels ch
WHERE
s.time_id = t.time_id
AND s.cust_id = c.cust_id
AND s.channel_id = ch.channel_id
AND c.cust_state_province = 'CA'
AND ch.channel_desc in ('Internet','Catalog')
AND t.calendar_quarter_desc IN ('1999-Q1','1999-Q2')
GROUP BY
ch.channel_class
, c.cust_city
, t.calendar_quarter_desc;


Star_transform

もう一つ, star transformationといえば, vector transformationも書かないと. この実行計画という名のレントゲン写真も一目見れば忘れることはないという特徴を持っています.
全く同じSQLでも可能ですが、star transformationのようにディメンジョン表でファクト表のデータが十分に絞りきれない場合やright-deep joinでもハッシュ結合が重すぎてParallel Queryにしても伸び悩むケースでは, ほぼ結合を行わない(行っても結合する行数が少ないので影響がすくない) vector transformの出番ですよね.
KEY VECTOR USEでディメンジョン表からin-memory accumulatorと呼ばれる多次元構造体を作成し, TABLE ACCESS INMEMORY FULLでファクト表を高速に読み出しつつ, in-memory accumulator上で集計. ディメンジョン表をファクト表を結合しないので巨大なハッシュ結合によるtemp落ちからも解放されます.
Noteセクションに- vector transformation used for this statementとリストされます. 特徴を見分けやすいですよね.

SELECT
/*+
VECTOR_TRANSFORM
*/
ch.channel_class
, c.cust_city
, t.calendar_quarter_desc
, SUM(s.amount_sold) sales_amount
FROM
sales s
, times t
, customers c
, channels ch
WHERE
s.time_id = t.time_id
AND s.cust_id = c.cust_id
AND s.channel_id = ch.channel_id
GROUP BY
ch.channel_class
, c.cust_city
, t.calendar_quarter_desc;

Vector_transform

続きを読む "実行計画は、SQL文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 おまけ#1"

| | コメント (0)

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





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

| | コメント (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文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 Day 24"

| | コメント (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




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

| | コメント (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文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 Day 22"

| | コメント (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編 (全部俺)Advent Calendar 2019 Day 21"

| | コメント (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文のレントゲン写真だ! Oracle Database編 (全部俺)Advent Calendar 2019 Day 20"

| | コメント (0)