Chasing the optimizer

Mauro Pagano
Mauro PaganoInfrastructure Senior Principal at Accenture Enkitec Group
Chasing	the	optimizer,
step	by	step
Mauro	Pagano
Agenda
• Optimizer
– Introduction
– Query	Blocks
– Physical	Optimization
– Logical	Optimization
– Common	Transformations
• Real-life	example
2
Trivia
• How	many	joins	evaluated	for	this	SQL?	12.1
SELECT e1.email, jh.job_id
FROM employees e1,
job_history jh
WHERE e1.employee_id = jh.employee_id
AND jh.start_date > '01-JAN-01'
AND e1.salary > (SELECT /*+ QB_NAME(SQ1) */ AVG(e2.salary)
FROM employees e2
WHERE e1.department_id = e2.department_id)
AND e1.department_id IN (SELECT /*+ QB_NAME(SQ2) */ d.department_id
FROM departments d,
locations l
WHERE d.location_id = l.location_id
AND l.country_id = 'US')
grep -c 'Join order[' cdb1_ora_5541.trc
198
3
A	day	in	the	life	of	the	optimizer
• Generate	an	optimal	plan
• Multiple	challenges
– Partial	knowledge	of	data	and	query	(stats/binds)
– Short	amount	of	time	(ms)
– Use	as	little	CPU	and	memory	as	possible
4
Hated	and	blamed	by	everybody
5
How	to	make	it	out	alive?
• Play	it	smart!
• Two	phases	optimization	
– Logical	and	Physical
• Logical	phase	transforms	SQL
– Trying	to	find	potentially	better	forms
– Open	the	door	to	better	plans
• Physical	phase	
– Identify	optimal	access	to	objects	involved
6
Working	together
• Logical	opt	output	input	for	Physical	opt
• Multiple	iterations	back	and	forth
7
Query Logical Optimizer
Physical Optimizer
Execution
Plan
Query	Block
• SQL	can	be	complex
– Made	of	smaller	SQLs	(each	is	a	QB)
– QBs	correlate	to	each	other
• QB	is	optimizer	unit	of	optimization
– Logical	opt	“reshapes”	query	blocks
– Physical	opt	find	optimal	way	to	execute	each	QB
8
Before	we	move	on
DISCLAIMER:
DON’T	TRUST	MAURO
(or	anybody	else)
Ask	for	evidence	or	test	it	yourself,	always!
9
How	many	QBs?
create table t1 as select * from dba_objects;
create table t2 as select * from dba_objects;
select owner, object_name
from t1
where last_ddl_time >
(select median(last_ddl_time)
from t2
where t1.owner = t2.owner);
10
Registered qb: SEL$1 0x71b6df90 (PARSER)
---------------------
QUERY BLOCK SIGNATURE
---------------------
signature (): qb_name=SEL$1 nbfros=1 flg=0
fro(0): flg=4 objn=24765
hint_alias="T1"@"SEL$1"
Registered qb: SEL$2 0x71b5e260 (PARSER)
---------------------
QUERY BLOCK SIGNATURE
---------------------
signature (): qb_name=SEL$2 nbfros=1 flg=0
fro(0): flg=4 objn=24766
hint_alias="T2"@"SEL$2"
How	many	QBs?
create table t1 as select * from dba_objects;
create table t2 as select * from dba_objects;
select *
from t1
union all
select *
from t2;
11
Registered qb: SEL$1 0x719d65b8 (PARSER)
---------------------
QUERY BLOCK SIGNATURE
---------------------
signature (): qb_name=SEL$1 nbfros=1 flg=0
fro(0): flg=4 objn=24765
hint_alias="T1"@"SEL$1"
Registered qb: SET$1 0x719c6610 (PARSER)
---------------------
QUERY BLOCK SIGNATURE
---------------------
signature (): qb_name=SET$1 nbfros=1 flg=0
fro(0): flg=0 objn=0
hint_alias="NULL_HALIAS"@"SET$1"
Registered qb: SEL$2 0x719c6c68 (PARSER)
---------------------
QUERY BLOCK SIGNATURE
---------------------
signature (): qb_name=SEL$2 nbfros=1 flg=0
fro(0): flg=4 objn=24766
hint_alias="T2"@"SEL$2"
Physical	optimizer
• Been	around	for	a	long	time
– The	one	to	always	get	blamed	(*)
– Lots	of	literature	about	it
• Goal:	find	optimal	exec	plan	for	QB
– The	“calculator”	part	of	the	optimizer
– Identify	driver	table	and	access	method	for	it
– Identify	optimal	join	order	and	join	methods
12
How	does	it	look	in	10053?
• Roughly between	these	two	text	blocks
---------------------
QUERY	BLOCK	SIGNATURE
---------------------
signature	(optimizer):	qb_name=SEL$683B0107 nbfros=1	flg=0
fro(0):	flg=0	objn=24766	hint_alias="T2"@"SEL$2”
-----------------------------
SYSTEM	STATISTICS	INFORMATION
.....
…..
.....
Final	cost	for	query	block	SEL$683B0107	(#2)	- All	Rows	Plan:
Best	join	order:	1
Cost:	80.6652 Degree:	1		Card:	20353.0000		Bytes:	284942
Resc:	80.6652		Resc_io:	79.0000		Resc_cpu:	52711834
Resp:	80.6652		Resp_io:	79.0000		Resc_cpu:	52711834
13
How	does	it	look	in	10053?	(2)
• Statistics	report	objects	in	QB
• Best	access	path	per	object	identified
– At	this	stage	the	objects	are	disconnected
BASE	STATISTICAL	INFORMATION
***********************
Table	Stats::
Table:	T2		Alias:	T2
#Rows:	20353		#Blks:		285		AvgRowLen:		90.00		ChainCnt:		0.00
Column	(#1):	OWNER(
AvgLen:	6	NDV:	14	Nulls:	0	Density:	0.071429
Access	path	analysis	for	T2
***************************************
SINGLE	TABLE	ACCESS	PATH
Single	Table	Cardinality	Estimation	for	T2[T2]
Table:	T2		Alias:	T2
Card:	Original:	20353.000000		Rounded:	20353		Computed:	20353.00		Non	Adjusted:	20353.00
Access	Path:	TableScan
Cost:		79.25		Resp:	79.25		Degree:	0
Cost_io:	79.00		Cost_cpu:	7931980
Resp_io:	79.00		Resp_cpu:	7931980
Best::	AccessPath:	TableScan
Cost:	79.25		Degree:	1		Resp:	79.25		Card:	20353.00		Bytes:	0
14
How	does	it	look	in	10053?	(3)
• Joins	evaluated	and	cheapest	one	selected
Permutations	for	Starting	Table	:0
Join	order[1]:		T1[T1]#0		T2[T2]#1
***************
Now	joining:	T2[T2]#1
***************
…
***********************
Best	so	far:		Table#:	0		cost:	79.2506		card:	20352.0000		bytes:	936192
Table#:	1		cost:	164297.6779		card:	29587446.8571		bytes:	1775246820
***********************
Join	order[2]:		T2[T2]#1		T1[T1]#0
***************
Now	joining:	T1[T1]#0
***************
….
Join	order	aborted:	cost	>	best	plan	cost
15
Logical	Optimizer
• The	“brain”	of	the	optimizer
• Applies	transformations	to	SQL
– Multiple	transformations	per	QB
– MUST keep	semantics	of	query
• Use	two	approaches
– Heuristic-based	trans	->	always	beneficial
– Cost-based	trans	->	“it	depends”	beneficial
16
Working	together	(2)
• Heuristic-b	and	cost-b	work	together
• Physical	optimizer	works	on	their	output
17
Query
Heuristic-based
Transformation
Physical Optimizer
Execution
Plan
Cost-based
Transformation
Heuristic-based	transformations
• Apply	those	changes	always	beneficial
– Filter	and	project	as	soon	as	possible
– Eliminate	redundant	operations
– Reduce	number	of	QBs	(merge)
• Less	QBs	means	more	permutations	per	QB
• Applied	before	cost-based
– And	sometime	after	cost-based	too
18
Cost-based	transformations
• Require	costing	to	determine	if	beneficial
– Physical	optimizer	costs	with	trans	ON/OFF,	cheapest	
wins
• CBQT	Framework
– Orchestrates	multiple	transformations
• Interleaved	(one	on	top	of	another)
• Juxtaposed	(either	one	or	another)
– Allows	new	transformations	to	be	plugged	in
– Time	savvy	(limit	search	space,	annotations,	etc)
19
How	many	transformations?
• A	LOT!
• Can	change	plan	very	little	and/or	very	much
• Dependent	on	coding	style
• Some	are	very	common
– Subquery unnesting (heuristic	and	cost-based)
– View	merging	(heuristic	and	cost-based)
– Join	Predicate	Push	Down	(mostly	cost-based	today)
20
Subquery Unnesting
select *
from t1
where object_id in (
select object_id
from t2);
-----------------------------------
| Id | Operation | Name |
-----------------------------------
| 0 | SELECT STATEMENT | |
|* 1 | FILTER | |
| 2 | TABLE ACCESS FULL| T1 |
|* 3 | TABLE ACCESS FULL| T2 |
21
select *
from t1, t2
where t1.object_id s=
t2.object_id;
-------------------------------------
| Id | Operation | Name |
-------------------------------------
| 0 | SELECT STATEMENT | |
|* 1 | HASH JOIN RIGHT SEMI| |
| 2 | TABLE ACCESS FULL | T2 |
| 3 | TABLE ACCESS FULL | T1 |
Easy	to	spot
FILTER	operation	is	gone
View	Merging
select t1.*
from t1,
(select object_id
from t2) t2
where t1.object_id =
t2.object_id;
------------------------------------
| Id | Operation | Name |
------------------------------------
| 0 | SELECT STATEMENT | |
|* 1 | HASH JOIN | |
| 2 | VIEW | |
| 3 | TABLE ACCESS FULL| T2 |
| 4 | TABLE ACCESS FULL | T1 |
22
select t1.*
from t1, t2
where t1.object_id =
t2.object_id;
--------------------------------------+
| Id | Operation | Name |
--------------------------------------+
| 0 | SELECT STATEMENT | |
| 1 | HASH JOIN | |
| 2 | TABLE ACCESS FULL | T2 |
| 3 | TABLE ACCESS FULL | T1 |
Easy	to	spot
VIEW	operation	is	gone
Join	Predicate	Push	Down
select t1.*
from t1,
(select object_id
from t2) t2
where t1.object_id =
t2.object_id(+);
--------------------------------------
| Id | Operation | Name |
--------------------------------------
| 0 | SELECT STATEMENT | |
|* 1 | HASH JOIN RIGHT OUTER| |
| 2 | VIEW | |
| 3 | TABLE ACCESS FULL | T2 |
| 4 | TABLE ACCESS FULL | T1 |
23
select t1.*
from t1,
(select object_id
from t2
where t1.object_id =
t2.object_id(+)) t2
----------------------------------------
| Id | Operation | Name |
----------------------------------------
| 0 | SELECT STATEMENT | |
| 1 | NESTED LOOPS OUTER | |
| 2 | TABLE ACCESS FULL | T1 |
| 3 | VIEW PUSHED PREDICATE | |
|* 4 | TABLE ACCESS FULL | T2 |
Easy	to	spot
VIEW	operation	shows	
PUSH	occurred
So	far	we	learned
• CBO	life	is	tough	J
• SQL	is	split	and	optimized	in	chunks	(QBs)
• Logical	Optim modifies	QBs	(1+)
• Physical	Optim costs	changed	QBs	(1)
• Cheapest	plan	(Logical	+	Physical)	wins
• Some	transformations	are	common
• It	all	sounds	pretty	simple,	right?
24
How	does	it	look	in	10053?
• This	is	where	things	get	tricky
– No	way	out,	10053	is	source	of	truth
• Average	SQL	produces	100k/250k+	rows	trace
– Trace	not	designed	to	be	summarized
– Supposed	to	be	READ	by	you
– Very	very	verbose	(and	sometimes	not	enough	L)
• We	need	a	plan!
• Easier	to	show	with	an	example
25
Let	the	fun	begin
Objects	from	HR	sample	schema
SELECT e1.email, jh.job_id
FROM employees e1,
job_history jh
WHERE e1.employee_id = jh.employee_id
AND jh.start_date > '01-JAN-01'
AND e1.salary > (SELECT AVG(e2.salary)
FROM employees e2
WHERE e1.department_id = e2.department_id)
AND e1.department_id IN (SELECT d.department_id
FROM departments d,
locations l
WHERE d.location_id = l.location_id
AND l.country_id = 'US’)
26
This	is	the	final	plan
-------------------------------------------------------------------------
| Id | Operation | Name |
-------------------------------------------------------------------------
| 0 | SELECT STATEMENT | |
|* 1 | FILTER | |
|* 2 | HASH JOIN | |
|* 3 | TABLE ACCESS BY INDEX ROWID BATCHED| JOB_HISTORY |
|* 4 | INDEX SKIP SCAN | JHIST_EMP_ID_ST_DATE_PK |
| 5 | TABLE ACCESS FULL | EMPLOYEES |
| 6 | NESTED LOOPS | |
| 7 | TABLE ACCESS BY INDEX ROWID | DEPARTMENTS |
|* 8 | INDEX UNIQUE SCAN | DEPT_ID_PK |
|* 9 | TABLE ACCESS BY INDEX ROWID | LOCATIONS |
|* 10 | INDEX UNIQUE SCAN | LOC_ID_PK |
| 11 | SORT AGGREGATE | |
| 12 | TABLE ACCESS BY INDEX ROWID BATCHED| EMPLOYEES |
|* 13 | INDEX RANGE SCAN | EMP_DEPARTMENT_IX |
-------------------------------------------------------------------------
27
No,	it’s	this	one
--------------------------------------------------------------------------+
| Id | Operation | Name |
--------------------------------------------------------------------------+
| 0 | SELECT STATEMENT | |
| 1 | NESTED LOOPS | |
| 2 | NESTED LOOPS SEMI | |
| 3 | NESTED LOOPS | |
| 4 | TABLE ACCESS BY INDEX ROWID BATCHED | JOB_HISTORY |
| 5 | INDEX SKIP SCAN | JHIST_EMP_ID_ST_DATE_PK|
| 6 | TABLE ACCESS BY INDEX ROWID | EMPLOYEES |
| 7 | INDEX UNIQUE SCAN | EMP_EMP_ID_PK |
| 8 | VIEW PUSHED PREDICATE | VW_NSO_2 |
| 9 | NESTED LOOPS | |
| 10 | TABLE ACCESS BY INDEX ROWID | DEPARTMENTS |
| 11 | INDEX UNIQUE SCAN | DEPT_ID_PK |
| 12 | TABLE ACCESS BY INDEX ROWID | LOCATIONS |
| 13 | INDEX UNIQUE SCAN | LOC_ID_PK |
| 14 | VIEW PUSHED PREDICATE | VW_SQ_1 |
| 15 | FILTER | |
| 16 | SORT AGGREGATE | |
| 17 | TABLE ACCESS BY INDEX ROWID BATCHED | EMPLOYEES |
| 18 | INDEX RANGE SCAN | EMP_DEPARTMENT_IX |
--------------------------------------------------------------------------+
28
Sorry,	it’s	this	one
---------------------------------------------------------------------------
| Id | Operation | Name |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | |
|* 1 | FILTER | |
| 2 | NESTED LOOPS SEMI | |
| 3 | NESTED LOOPS | |
|* 4 | TABLE ACCESS BY INDEX ROWID BATCHED | JOB_HISTORY |
|* 5 | INDEX SKIP SCAN | JHIST_EMP_ID_ST_DATE_PK |
| 6 | TABLE ACCESS BY INDEX ROWID | EMPLOYEES |
|* 7 | INDEX UNIQUE SCAN | EMP_EMP_ID_PK |
| 8 | VIEW PUSHED PREDICATE | VW_NSO_1 |
| 9 | NESTED LOOPS | |
| 10 | TABLE ACCESS BY INDEX ROWID | DEPARTMENTS |
|* 11 | INDEX UNIQUE SCAN | DEPT_ID_PK |
|* 12 | TABLE ACCESS BY INDEX ROWID BATCHED| LOCATIONS |
|* 13 | INDEX RANGE SCAN | LOC_COUNTRY_IX |
| 14 | SORT AGGREGATE | |
| 15 | TABLE ACCESS BY INDEX ROWID BATCHED | EMPLOYEES |
|* 16 | INDEX RANGE SCAN | EMP_DEPARTMENT_IX |
---------------------------------------------------------------------------
29
Ops,	it’s	this	one,	I	swear!
------------------------------------------------------------------------------
| Id | Operation | Name |
------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | |
|* 1 | FILTER | |
| 2 | NESTED LOOPS | |
| 3 | NESTED LOOPS | |
| 4 | NESTED LOOPS | |
| 5 | VIEW | VW_NSO_1 |
| 6 | HASH UNIQUE | |
| 7 | NESTED LOOPS SEMI | |
| 8 | VIEW | index$_join$_004 |
|* 9 | HASH JOIN | |
| 10 | INDEX FAST FULL SCAN | DEPT_ID_PK |
| 11 | INDEX FAST FULL SCAN | DEPT_LOCATION_IX |
|* 12 | TABLE ACCESS BY INDEX ROWID BATCHED| LOCATIONS |
|* 13 | INDEX RANGE SCAN | LOC_COUNTRY_IX |
| 14 | TABLE ACCESS BY INDEX ROWID BATCHED | EMPLOYEES |
|* 15 | INDEX RANGE SCAN | EMP_DEPARTMENT_IX |
|* 16 | INDEX RANGE SCAN | JHIST_EMP_ID_ST_DATE_PK |
|* 17 | TABLE ACCESS BY INDEX ROWID | JOB_HISTORY |
| 18 | SORT AGGREGATE | |
| 19 | TABLE ACCESS BY INDEX ROWID BATCHED | EMPLOYEES |
|* 20 | INDEX RANGE SCAN | EMP_DEPARTMENT_IX |
------------------------------------------------------------------------------
30
Recap
What	did	I	say	before?
DON’T	TRUST	MAURO
(or	anybody	else)
Let’s	look	at	10053	and	stop	guessing!
31
Starting	point
Objects	from	HR	sample	schema
SELECT e1.email, jh.job_id
FROM employees e1,
job_history jh
WHERE e1.employee_id = jh.employee_id
AND jh.start_date > '01-JAN-01'
AND e1.salary > (SELECT AVG(e2.salary)
FROM employees e2
WHERE e1.department_id = e2.department_id)
AND e1.department_id IN (SELECT d.department_id
FROM departments d,
locations l
WHERE d.location_id = l.location_id
AND l.country_id = 'US’)
45k	10053	trace	file
32
How	many	QBs?
Registered qb: SEL$1 0x4cf0e098 (PARSER)
signature (): qb_name=SEL$1 nbfros=2 flg=0
fro(0): flg=4 objn=96089 hint_alias="E1"@"SEL$1"
fro(1): flg=4 objn=96093 hint_alias="JH"@"SEL$1"
Registered qb: SEL$2 0x4cf04f00 (PARSER)
signature (): qb_name=SEL$2 nbfros=1 flg=0
fro(0): flg=4 objn=96089 hint_alias="E2"@"SEL$2"
Registered qb: SEL$3 0x4cf03f60 (PARSER)
signature (): qb_name=SEL$3 nbfros=2 flg=0
fro(0): flg=4 objn=96084 hint_alias="D"@"SEL$3"
fro(1): flg=4 objn=96081 hint_alias="L"@"SEL$3”
• Think	of	3	QBs	as	3	pieces	of	LEGO
• Transformed	and	cost	N	times
33
Which	transformations	applied?
• QB	Registry	in	10053	tells	you	the	story
• All	(most)	of	the	transformations	for	each	QB
– Includes	name	of	new	QBs
– Indentation	for	parent/child	relationship
– QBs	part	of	best	plan	have	[FINAL]
– QBs	at	the	same	level	are	crossroads
• Used	as	a	map	to	chase	CBO	actions
– Enable	specific	searches	in	10053
34
Query	Block	Registry
• Each	QB	dumped	with	transformations
Query Block Registry:
SEL$3 0x4c50a700 (PARSER) [FINAL]
SEL$8771BF6C 0x0 (SUBQUERY UNNEST SEL$1; SEL$3;)
SEL$7C12A527 0x0 (COMPLEX SUBQUERY UNNEST SEL$8771BF6C)
SEL$5DB0472E 0x0 (SPLIT/MERGE QUERY BLOCKS SEL$8771BF6C)
SEL$2AD7F9D9 0x0 (PUSHED PREDICATE SEL$291F8F59; SEL$8771BF6C; "VW_NSO_11"@"SEL$8771BF6C" 4)
SEL$2E20A9F9 0x0 (SUBQUERY UNNEST SEL$7511BFD2; SEL$3; SEL$2;)
SEL$CC348667 0x0 (COMPLEX SUBQUERY UNNEST SEL$2E20A9F9)
SEL$291F8F59 0x0 (SUBQ INTO VIEW FOR COMPLEX UNNEST SEL$3)
SEL$555A942D 0x0 (VIEW MERGE SEL$C149BB3C; SEL$291F8F59)
SEL$C149BB3C 0x0 (PROJECTION VIEW FOR CVM SEL$291F8F59)
SEL$555A942D 0x0 (VIEW MERGE SEL$C149BB3C; SEL$291F8F59)
SEL$2AD7F9D9 0x0 (PUSHED PREDICATE SEL$291F8F59; SEL$8771BF6C; "VW_NSO_11"@"SEL$8771BF6C" 4)
SEL$2 0x4c50b6a0 (PARSER)
SEL$C772B8D1 0x4c50ff78 (SUBQUERY UNNEST SEL$7511BFD2; SEL$2) [FINAL]
SEL$841DDE77 0x0 (VIEW MERGE SEL$C772B8D1; SEL$683B0107)
SEL$C6423BE4 0x0 (PUSHED PREDICATE SEL$683B0107; SEL$C772B8D1; "VW_SQ_1"@"SEL$7511BFD2" 4)
SEL$2E20A9F9 0x0 (SUBQUERY UNNEST SEL$7511BFD2; SEL$3; SEL$2;)
...
SEL$683B0107 0x4c50b6a0 (SUBQ INTO VIEW FOR COMPLEX UNNEST SEL$2) [FINAL]
SEL$841DDE77 0x0 (VIEW MERGE SEL$C772B8D1; SEL$683B0107)
SEL$C6423BE4 0x0 (PUSHED PREDICATE SEL$683B0107; SEL$C772B8D1; "VW_SQ_1"@"SEL$7511BFD2" 4)
SEL$1 0x4c50ff78 (PARSER)
SEL$8771BF6C 0x0 (SUBQUERY UNNEST SEL$1; SEL$3;)
...
SEL$7511BFD2 0x4c50ff78 (VIEW ADDED SEL$1)
SEL$C772B8D1 0x4c50ff78 (SUBQUERY UNNEST SEL$7511BFD2; SEL$2) [FINAL]
...
SEL$2E20A9F9 0x0 (SUBQUERY UNNEST SEL$7511BFD2; SEL$3; SEL$2;)
...
35
Final	plan	is
------------------------------------------------------------+-----------------------------------+
| Id | Operation | Name | Rows | Bytes | Cost | Time |
------------------------------------------------------------+-----------------------------------+
| 0 | SELECT STATEMENT | | | | 10 | |
| 1 | FILTER | | | | | |
| 2 | NESTED LOOPS | | 2 | 148 | 8 | 00:00:01 |
| 3 | NESTED LOOPS | | 17 | 148 | 8 | 00:00:01 |
| 4 | HASH JOIN | | 17 | 765 | 7 | 00:00:01 |
| 5 | VIEW | VW_SQ_1 | 11 | 286 | 4 | 00:00:01 |
| 6 | HASH GROUP BY | | 11 | 77 | 4 | 00:00:01 |
| 7 | TABLE ACCESS STORAGE FULL | EMPLOYEES | 107 | 749 | 3 | 00:00:01 |
| 8 | TABLE ACCESS STORAGE FULL | EMPLOYEES | 107 | 2033 | 3 | 00:00:01 |
| 9 | INDEX RANGE SCAN | JHIST_EMPLOYEE_IX| 1 | | 0 | |
| 10 | TABLE ACCESS BY INDEX ROWID | JOB_HISTORY | 1 | 29 | 1 | 00:00:01 |
| 11 | NESTED LOOPS | | 1 | 13 | 2 | 00:00:01 |
| 12 | TABLE ACCESS BY INDEX ROWID | DEPARTMENTS | 1 | 7 | 1 | 00:00:01 |
| 13 | INDEX UNIQUE SCAN | DEPT_ID_PK | 1 | | 0 | |
| 14 | TABLE ACCESS BY INDEX ROWID | LOCATIONS | 1 | 6 | 1 | 00:00:01 |
| 15 | INDEX UNIQUE SCAN | LOC_ID_PK | 1 | | 0 | |
------------------------------------------------------------+-----------------------------------+
1 - filter( IS NOT NULL)
4 - access("E1"."DEPARTMENT_ID"="ITEM_1")
4 - filter("E1"."SALARY">"AVG(E2.SALARY)")
9 - access("E1"."EMPLOYEE_ID"="JH"."EMPLOYEE_ID")
36
10 - filter(("JH"."START_DATE">'01-JAN-01' AND "END_DATE">'01-JAN-01'))
13 - access("D"."DEPARTMENT_ID"=:B1)
14 - filter("L"."COUNTRY_ID"='US')
15 - access("D"."LOCATION_ID"="L"."LOCATION_ID")
How	to	attack	10053?
• Keep	it	simple
• Remember:	multiple	internal	QB	trans	from	A	to	B
• Ignore	“noise”,	focus	on	what	you	seek
> wc –l MAURRRO1_ora_119219_test.trc
44612 MAURRRO1_ora_119219_test.trc
> grep -nE '^[A-Z]{2,}:|Registe’ MAURRRO1_ora_119219_test.trc | grep -v 'CBRID…' | wc -l
377
• Use	physical	opt	input	QB	as	anchor
– Last	one	before	big	jump	in	10053
– QB	represent	the	valid	status	
37
Where	are	we?	#1
38
Ok	one	step	at	a	time
1930:SU: Unnesting query blocks in query block SEL$1 (#1) that are valid to unnest.
1935:SU: Considering subquery unnest on query block SEL$1 (#1).
1936:SU: Checking validity of unnesting subquery SEL$2 (#3)
1937:SU: Passed validity checks, but requires costing.
1938:SU: Checking validity of unnesting subquery SEL$3 (#2)
1939:SU: Passed validity checks, but requires costing.
1940:SU: Using search type: exhaustive
1941:SU: Starting iteration 1, state space = (2,3) : (1,1)
1945:Registered qb: SEL$683B0107 0x96361e50 (SUBQ INTO VIEW FOR COMPLEX UNNEST SEL$2)
1952:Registered qb: SEL$7511BFD2 0x962788a8 (VIEW ADDED SEL$1)
1962:Registered qb: SEL$291F8F59 0x96276b58 (SUBQ INTO VIEW FOR COMPLEX UNNEST SEL$3)
1970:Registered qb: SEL$2E20A9F9 0x962788a8 (SUBQUERY UNNEST SEL$7511BFD2; SEL$3; SEL$2;)
2002:SU: Costing transformed query.
2003:CBQT: Looking for cost annotations for query block SEL$683B0107, key = SEL$683B0107_00002002_4
2004:CBQT: Could not find stored cost annotations.
2005:CBQT: Looking for cost annotations for query block SEL$291F8F59, key = SEL$291F8F59_00002002_4
2006:CBQT: Could not find stored cost annotations.
…
5151:CBQT: Saved costed qb# 3 (SEL$683B0107), key = SEL$683B0107_00002002_4
5152:CBQT: Saved costed qb# 2 (SEL$291F8F59), key = SEL$291F8F59_00002002_4
5153:CBQT: Saved costed qb# 1 (SEL$2E20A9F9), key = SEL$2E20A9F9_00000000_0
39
Where	are	we?	#2
40
Digging	into	10053
• Use	the	QB	name	to	search	for	costs
2160 Final cost for query block SEL$683B0107 (#3) - All Rows Plan:
2161 Best join order: 1
2162 Cost: 4.002661 Degree: 1 Card: 107.000000 Bytes: 749.000000
2646 Final cost for query block SEL$291F8F59 (#2) - All Rows Plan:
2647 Best join order: 1
2648 Cost: 3.218206 Degree: 1 Card: 14.000000 Bytes: 182.000000
2683 signature (optimizer): qb_name=SEL$2E20A9F9 nbfros=4 flg=0
2684 fro(0): flg=0 objn=91753 hint_alias="E1"@"SEL$1"
2685 fro(1): flg=0 objn=91757 hint_alias="JH"@"SEL$1"
2686 fro(2): flg=1 objn=0 hint_alias="VW_NSO_2"@"SEL$2E20A9F9"
2687 fro(3): flg=1 objn=0 hint_alias="VW_SQ_1"@"SEL$7511BFD2"
…
5140 Final cost for query block SEL$2E20A9F9 (#1) - All Rows Plan:
5141 Best join order: 4
5142 Cost: 11.366818 Degree: 1 Card: 2.000000 Bytes: 174.000000
5151:CBQT: Saved costed qb# 3 (SEL$683B0107), key = SEL$683B0107_00002002_4
5152:CBQT: Saved costed qb# 2 (SEL$291F8F59), key = SEL$291F8F59_00002002_4
5153:CBQT: Saved costed qb# 1 (SEL$2E20A9F9), key = SEL$2E20A9F9_00000000_0
41
Where	are	we?	#3
42
First	interleaved	transformation
<<skipped interleaved DP>>
8254:SU: Considering interleaved join pred push down
8255:SU: Unnesting subquery query block SEL$2 (#3)Subquery removal for query block SEL$2 (#3)
8258:SU: Transform an ANY subquery to semi-join or distinct.
8259:JPPD: Checking validity of push-down in query block SEL$2E20A9F9 (#1)
8260:JPPD: Checking validity of push-down from query block SEL$2E20A9F9 (#1) to query block SEL$291F8F59 (#2)
8262:JPPD: Passed validity checks
8263:JPPD: Checking validity of push-down from query block SEL$2E20A9F9 (#1) to query block SEL$683B0107 (#3)
8265:JPPD: Passed validity checks
8266:JPPD: JPPD: Pushdown from query block SEL$2E20A9F9 (#1) passed validity checks.
8268:JPPD: Using search type: linear
8269:JPPD: Considering join predicate push-down
8270:JPPD: Starting iteration 1, state space = (2,3) : (0,0)
<<copy QB here>>
8286:JPPD: Performing join predicate push-down (no transformation phase) from query block SEL$2E20A9F9 (#1) to query block
SEL$291F8F59 (#2)
8288:JPPD: Performing join predicate push-down (no transformation phase) from query block SEL$2E20A9F9 (#1) to query block
SEL$683B0107 (#3)
8312:JPPD: Costing transformed query.
…
11461:CBQT: Saved costed qb# 3 (SEL$683B0107), key = SEL$683B0107_00042002_4
11462:CBQT: Saved costed qb# 2 (SEL$291F8F59), key = SEL$291F8F59_00042002_4
11463:CBQT: Saved costed qb# 1 (SEL$2E20A9F9), key = SEL$2E20A9F9_00000000_0
43
Where	are	we?	#4
44
Digging	into	10053
• Use	the	QB	name	to	search	for	costs
8470 Final cost for query block SEL$683B0107 (#3) - All Rows Plan:
8471 Best join order: 1
8472 Cost: 4.002661 Degree: 1 Card: 107.000000 Bytes: 749.000000
8956 Final cost for query block SEL$291F8F59 (#2) - All Rows Plan:
8957 Best join order: 1
8958 Cost: 3.218206 Degree: 1 Card: 14.000000 Bytes: 182.000000
8993 signature (optimizer): qb_name=SEL$2E20A9F9 nbfros=4 flg=0
8994 fro(0): flg=0 objn=91753 hint_alias="E1"@"SEL$1"
8995 fro(1): flg=0 objn=91757 hint_alias="JH"@"SEL$1"
8996 fro(2): flg=1 objn=0 hint_alias="VW_NSO_6"@"SEL$2E20A9F9"
8997 fro(3): flg=1 objn=0 hint_alias="VW_SQ_5"@"SEL$7511BFD2"
…
11450 Final cost for query block SEL$2E20A9F9 (#1) - All Rows Plan:
11451 Best join order: 4
11452 Cost: 11.366818 Degree: 1 Card: 2.000000 Bytes: 174.000000
11461:CBQT: Saved costed qb# 3 (SEL$683B0107), key = SEL$683B0107_00042002_4
11462:CBQT: Saved costed qb# 2 (SEL$291F8F59), key = SEL$291F8F59_00042002_4
11463:CBQT: Saved costed qb# 1 (SEL$2E20A9F9), key = SEL$2E20A9F9_00000000_0
11464:JPPD: Updated best state, Cost = 11.366818
45
More	JPPD	iterations
11465:JPPD: Starting iteration 2, state space = (2,3) : (1,0)
11466:JPPD: Performing join predicate push-down (candidate phase) from query block SEL$2E20A9F9 (#1) to query block
SEL$291F8F59 (#2)
11467:JPPD: Pushing predicate "E1"."DEPARTMENT_ID"="VW_NSO_6"."DEPARTMENT_ID"
11469:JPPD: Push dest of pred 0x7fd396030c68 is qb 0x7fd396033fb8:query block SEL$291F8F59 (#2)
11471:JPPD: Performing join predicate push-down (no transformation phase) from query block SEL$2E20A9F9 (#1) to query
block SEL$683B0107 (#3)
11503:JPPD: Costing transformed query.
12363:CBQT: Looking for cost annotations for query block SEL$683B0107, key = SEL$683B0107_00002002_4
12364:CBQT: Replaced cost annotations in query block SEL$683B0107.
12365:CBQT: Looking for cost annotations for query block SEL$2AD7F9D9, key = SEL$2AD7F9D9_00082212_4
12366:CBQT: Could not find stored cost annotations.
…
13907:CBQT: Saved costed qb# 3 (SEL$683B0107), key = SEL$683B0107_00002002_4
13908:CBQT: Saved costed qb# 1 (SEL$2E20A9F9), key = SEL$2E20A9F9_00100200_0
13909:JPPD: Not update best state, Cost = 13.036576
…
46
Where	are	we?	#5
47
More	JPPD	iterations
…
13910:JPPD: Starting iteration 3, state space = (2,3) : (0,1)
13952:JPPD: Costing transformed query.
13953:CBQT: Looking for cost annotations for query block SEL$C6423BE4, key = SEL$C6423BE4_00082212_4
13954:CBQT: Could not find stored cost annotations.
13955:CBQT: Looking for cost annotations for query block SEL$291F8F59, key = SEL$291F8F59_00002002_4
13956:CBQT: Replaced cost annotations in query block SEL$291F8F59.
…
15338:JPPD: Not update best state, Cost = 28.256163
48
Where	are	we?	#6
49
Done	with	JPPD,	moving	on
15339:JPPD: Will not use JPPD from query block SEL$2E20A9F9 (#1)
15341:SU: Rejected interleaved query.
15342:SU: Finished interleaved join pred push down
15343:SU: Updated best state, Cost = 11.366818
15344:Registered qb: SEL$CC348667 0x962788a8 (COMPLEX SUBQUERY UNNEST SEL$2E20A9F9)
15354:SU: Starting iteration 2, state space = (2,3) : (1,0)
15356:Registered qb: SEL$8771BF6C 0x9607ed38 (SUBQUERY UNNEST SEL$1; SEL$3;)
15390:SU: Costing transformed query.
…
16988:SU: Considering interleaved complex view merging
16990:CVM: Considering view merge (candidate phase) in query block SEL$8771BF6C (#1)
16993:CVM: Considering view merge (candidate phase) in query block SEL$291F8F59 (#2)
16996:CVM: CBQT Marking query block SEL$291F8F59 (#2) as valid for CVM.
16997:CVM: Merging complex view SEL$291F8F59 (#2) into SEL$8771BF6C (#1).
17002:Registered qb: SEL$8771BF6C 0x96096420 (COPY SEL$8771BF6C)
17007:Registered qb: SEL$5DB0472E 0x96075e60 (SPLIT/MERGE QUERY BLOCKS SEL$8771BF6C)
17014:Registered qb: SEL$C149BB3C 0x96096420 (PROJECTION VIEW FOR CVM SEL$291F8F59)
17041:Registered qb: SEL$555A942D 0x96096420 (VIEW MERGE SEL$C149BB3C; SEL$291F8F59)
17075:SU: Costing transformed query.
…
20976:SU: Interleaved cost better than best so far.
50
Flash	forward
20977:SU: Finished interleaved complex view merging
20978:SU: Considering interleaved distinct placement
…
22396:SU: Rejected interleaved distinct placement.
22397:SU: Finished interleaved distinct placement
22398:SU: Considering interleaved join pred push down
…
25631:SU: Rejected interleaved query.
25632:SU: Finished interleaved join pred push down
25633:SU: Not update best state, Cost = 14.206022
…
25643:SU: Starting iteration 3, state space = (2,3) : (0,1)
…
27951:SU: Considering interleaved complex view merging
…
30186:SU: Considering interleaved distinct placement
…
30188:SU: Considering interleaved join pred push down
30200:JPPD: Starting iteration 1, state space = (3) : (0)
32118:JPPD: Updated best state, Cost = 10.133928
32119:JPPD: Starting iteration 2, state space = (3) : (1)
33561:JPPD: Not update best state, Cost = 27.023273
33562:JPPD: Will not use JPPD from query block SEL$C772B8D1 (#1)
…
33566:SU: Updated best state, Cost = 10.133928
33567:SU: Starting iteration 4, state space = (2,3) : (0,0)
51
Finally	the	end	J
34775:SU: Not update best state, Cost = 17.020791
34776:SU: Will not unnest subquery SEL$3 (#2)
34777:SU: Will unnest subquery SEL$2 (#3)
34778:SU: Reconstructing original query from best state.
…
52
Summary
• Logical	optimizer	changes	QBs
• Physical	optimizer	used	to	cost	changes
• QB	Registry	tracks	all	those	changes
– Can	be	used	to	find	the	cost	of	each	trans
– Find	if	trans	expected	was	even	considered
– Find	cost	of	trans	expected	vs selected
• It’s	not	hard	but	it	requires	practice
53
54
Contact	Information
• http://mauro-pagano.com
– Email
• mauro.pagano@gmail.com
– Download
• SQLd360	vYYMM (date)
– Pages
• SQLd360
55
1 of 55

Recommended

Ash masters : advanced ash analytics on Oracle by
Ash masters : advanced ash analytics on Oracle Ash masters : advanced ash analytics on Oracle
Ash masters : advanced ash analytics on Oracle Kyle Hailey
2.4K views127 slides
Same plan different performance by
Same plan different performanceSame plan different performance
Same plan different performanceMauro Pagano
1.2K views53 slides
Understanding my database through SQL*Plus using the free tool eDB360 by
Understanding my database through SQL*Plus using the free tool eDB360Understanding my database through SQL*Plus using the free tool eDB360
Understanding my database through SQL*Plus using the free tool eDB360Carlos Sierra
2.9K views19 slides
Understanding How is that Adaptive Cursor Sharing (ACS) produces multiple Opt... by
Understanding How is that Adaptive Cursor Sharing (ACS) produces multiple Opt...Understanding How is that Adaptive Cursor Sharing (ACS) produces multiple Opt...
Understanding How is that Adaptive Cursor Sharing (ACS) produces multiple Opt...Carlos Sierra
12.5K views44 slides
Oracle sql high performance tuning by
Oracle sql high performance tuningOracle sql high performance tuning
Oracle sql high performance tuningGuy Harrison
24K views56 slides
SQLd360 by
SQLd360SQLd360
SQLd360Mauro Pagano
1.3K views45 slides

More Related Content

What's hot

OOUG: Oracle transaction locking by
OOUG: Oracle transaction lockingOOUG: Oracle transaction locking
OOUG: Oracle transaction lockingKyle Hailey
3.9K views66 slides
Tanel Poder - Scripts and Tools short by
Tanel Poder - Scripts and Tools shortTanel Poder - Scripts and Tools short
Tanel Poder - Scripts and Tools shortTanel Poder
4.7K views34 slides
Oracle Performance Tuning Fundamentals by
Oracle Performance Tuning FundamentalsOracle Performance Tuning Fundamentals
Oracle Performance Tuning FundamentalsEnkitec
5.6K views84 slides
Adapting to Adaptive Plans on 12c by
Adapting to Adaptive Plans on 12cAdapting to Adaptive Plans on 12c
Adapting to Adaptive Plans on 12cMauro Pagano
1.7K views36 slides
Deep review of LMS process by
Deep review of LMS processDeep review of LMS process
Deep review of LMS processRiyaj Shamsudeen
2.2K views25 slides
Oracle db performance tuning by
Oracle db performance tuningOracle db performance tuning
Oracle db performance tuningSimon Huang
3.1K views123 slides

What's hot(20)

OOUG: Oracle transaction locking by Kyle Hailey
OOUG: Oracle transaction lockingOOUG: Oracle transaction locking
OOUG: Oracle transaction locking
Kyle Hailey3.9K views
Tanel Poder - Scripts and Tools short by Tanel Poder
Tanel Poder - Scripts and Tools shortTanel Poder - Scripts and Tools short
Tanel Poder - Scripts and Tools short
Tanel Poder4.7K views
Oracle Performance Tuning Fundamentals by Enkitec
Oracle Performance Tuning FundamentalsOracle Performance Tuning Fundamentals
Oracle Performance Tuning Fundamentals
Enkitec5.6K views
Adapting to Adaptive Plans on 12c by Mauro Pagano
Adapting to Adaptive Plans on 12cAdapting to Adaptive Plans on 12c
Adapting to Adaptive Plans on 12c
Mauro Pagano1.7K views
Oracle db performance tuning by Simon Huang
Oracle db performance tuningOracle db performance tuning
Oracle db performance tuning
Simon Huang3.1K views
SQL Plan Directives explained by Mauro Pagano
SQL Plan Directives explainedSQL Plan Directives explained
SQL Plan Directives explained
Mauro Pagano2.4K views
Troubleshooting Complex Performance issues - Oracle SEG$ contention by Tanel Poder
Troubleshooting Complex Performance issues - Oracle SEG$ contentionTroubleshooting Complex Performance issues - Oracle SEG$ contention
Troubleshooting Complex Performance issues - Oracle SEG$ contention
Tanel Poder44.1K views
Oracle Database SQL Tuning Concept by Chien Chung Shen
Oracle Database SQL Tuning ConceptOracle Database SQL Tuning Concept
Oracle Database SQL Tuning Concept
Chien Chung Shen2.1K views
Exploring Oracle Database Performance Tuning Best Practices for DBAs and Deve... by Aaron Shilo
Exploring Oracle Database Performance Tuning Best Practices for DBAs and Deve...Exploring Oracle Database Performance Tuning Best Practices for DBAs and Deve...
Exploring Oracle Database Performance Tuning Best Practices for DBAs and Deve...
Aaron Shilo2.1K views
Oracle Latch and Mutex Contention Troubleshooting by Tanel Poder
Oracle Latch and Mutex Contention TroubleshootingOracle Latch and Mutex Contention Troubleshooting
Oracle Latch and Mutex Contention Troubleshooting
Tanel Poder7.2K views
Tanel Poder - Performance stories from Exadata Migrations by Tanel Poder
Tanel Poder - Performance stories from Exadata MigrationsTanel Poder - Performance stories from Exadata Migrations
Tanel Poder - Performance stories from Exadata Migrations
Tanel Poder6.3K views
Oracle statistics by example by Mauro Pagano
Oracle statistics by exampleOracle statistics by example
Oracle statistics by example
Mauro Pagano1.6K views
Oracle X$TRACE, Exotic Wait Event Types and Background Process Communication by Tanel Poder
Oracle X$TRACE, Exotic Wait Event Types and Background Process CommunicationOracle X$TRACE, Exotic Wait Event Types and Background Process Communication
Oracle X$TRACE, Exotic Wait Event Types and Background Process Communication
Tanel Poder2.6K views
Stop the Chaos! Get Real Oracle Performance by Query Tuning Part 1 by SolarWinds
Stop the Chaos! Get Real Oracle Performance by Query Tuning Part 1Stop the Chaos! Get Real Oracle Performance by Query Tuning Part 1
Stop the Chaos! Get Real Oracle Performance by Query Tuning Part 1
SolarWinds1.5K views
Direct SGA access without SQL by Kyle Hailey
Direct SGA access without SQLDirect SGA access without SQL
Direct SGA access without SQL
Kyle Hailey2.9K views
Tanel Poder - Troubleshooting Complex Oracle Performance Issues - Part 2 by Tanel Poder
Tanel Poder - Troubleshooting Complex Oracle Performance Issues - Part 2Tanel Poder - Troubleshooting Complex Oracle Performance Issues - Part 2
Tanel Poder - Troubleshooting Complex Oracle Performance Issues - Part 2
Tanel Poder12.6K views
Analyzing and Interpreting AWR by pasalapudi
Analyzing and Interpreting AWRAnalyzing and Interpreting AWR
Analyzing and Interpreting AWR
pasalapudi64.2K views
Troubleshooting Complex Oracle Performance Problems with Tanel Poder by Tanel Poder
Troubleshooting Complex Oracle Performance Problems with Tanel PoderTroubleshooting Complex Oracle Performance Problems with Tanel Poder
Troubleshooting Complex Oracle Performance Problems with Tanel Poder
Tanel Poder959 views

Similar to Chasing the optimizer

Metadata Matters by
Metadata MattersMetadata Matters
Metadata Mattersafa reg
1.7K views60 slides
Understanding Query Optimization with ‘regular’ and ‘Exadata’ Oracle by
Understanding Query Optimization with ‘regular’ and ‘Exadata’ OracleUnderstanding Query Optimization with ‘regular’ and ‘Exadata’ Oracle
Understanding Query Optimization with ‘regular’ and ‘Exadata’ OracleGuatemala User Group
1.6K views76 slides
5 Cool Things About SQL by
5 Cool Things About SQL5 Cool Things About SQL
5 Cool Things About SQLConnor McDonald
65 views96 slides
Managing Statistics for Optimal Query Performance by
Managing Statistics for Optimal Query PerformanceManaging Statistics for Optimal Query Performance
Managing Statistics for Optimal Query PerformanceKaren Morton
1.7K views119 slides
Oracle Diagnostics : Joins - 1 by
Oracle Diagnostics : Joins - 1Oracle Diagnostics : Joins - 1
Oracle Diagnostics : Joins - 1Hemant K Chitale
594 views13 slides
A few things about the Oracle optimizer - 2013 by
A few things about the Oracle optimizer - 2013A few things about the Oracle optimizer - 2013
A few things about the Oracle optimizer - 2013Connor McDonald
55 views83 slides

Similar to Chasing the optimizer(20)

Metadata Matters by afa reg
Metadata MattersMetadata Matters
Metadata Matters
afa reg1.7K views
Understanding Query Optimization with ‘regular’ and ‘Exadata’ Oracle by Guatemala User Group
Understanding Query Optimization with ‘regular’ and ‘Exadata’ OracleUnderstanding Query Optimization with ‘regular’ and ‘Exadata’ Oracle
Understanding Query Optimization with ‘regular’ and ‘Exadata’ Oracle
Managing Statistics for Optimal Query Performance by Karen Morton
Managing Statistics for Optimal Query PerformanceManaging Statistics for Optimal Query Performance
Managing Statistics for Optimal Query Performance
Karen Morton1.7K views
A few things about the Oracle optimizer - 2013 by Connor McDonald
A few things about the Oracle optimizer - 2013A few things about the Oracle optimizer - 2013
A few things about the Oracle optimizer - 2013
Connor McDonald55 views
Writing efficient sql by j9soto
Writing efficient sqlWriting efficient sql
Writing efficient sql
j9soto469 views
SQLチューニング総合診療Oracle CloudWorld出張所 by Hiroshi Sekiguchi
SQLチューニング総合診療Oracle CloudWorld出張所SQLチューニング総合診療Oracle CloudWorld出張所
SQLチューニング総合診療Oracle CloudWorld出張所
The Hidden Face of Cost-Based Optimizer: PL/SQL Specific Statistics by Michael Rosenblum
The Hidden Face of Cost-Based Optimizer: PL/SQL Specific StatisticsThe Hidden Face of Cost-Based Optimizer: PL/SQL Specific Statistics
The Hidden Face of Cost-Based Optimizer: PL/SQL Specific Statistics
Michael Rosenblum210 views
Oracle dbms_xplan.display_cursor format by Franck Pachot
Oracle dbms_xplan.display_cursor formatOracle dbms_xplan.display_cursor format
Oracle dbms_xplan.display_cursor format
Franck Pachot205 views
SQL Macros - Game Changing Feature for SQL Developers? by Andrej Pashchenko
SQL Macros - Game Changing Feature for SQL Developers?SQL Macros - Game Changing Feature for SQL Developers?
SQL Macros - Game Changing Feature for SQL Developers?
Andrej Pashchenko319 views
Kernel Recipes 2017: Performance Analysis with BPF by Brendan Gregg
Kernel Recipes 2017: Performance Analysis with BPFKernel Recipes 2017: Performance Analysis with BPF
Kernel Recipes 2017: Performance Analysis with BPF
Brendan Gregg5.3K views
Kernel Recipes 2017 - Performance analysis Superpowers with Linux BPF - Brend... by Anne Nicolas
Kernel Recipes 2017 - Performance analysis Superpowers with Linux BPF - Brend...Kernel Recipes 2017 - Performance analysis Superpowers with Linux BPF - Brend...
Kernel Recipes 2017 - Performance analysis Superpowers with Linux BPF - Brend...
Anne Nicolas479 views
M|18 Querying Data at a Previous Point in Time by MariaDB plc
M|18 Querying Data at a Previous Point in TimeM|18 Querying Data at a Previous Point in Time
M|18 Querying Data at a Previous Point in Time
MariaDB plc1.2K views

Recently uploaded

Fleet Management Software in India by
Fleet Management Software in India Fleet Management Software in India
Fleet Management Software in India Fleetable
11 views1 slide
Ports-and-Adapters Architecture for Embedded HMI by
Ports-and-Adapters Architecture for Embedded HMIPorts-and-Adapters Architecture for Embedded HMI
Ports-and-Adapters Architecture for Embedded HMIBurkhard Stubert
21 views19 slides
SAP FOR CONTRACT MANUFACTURING.pdf by
SAP FOR CONTRACT MANUFACTURING.pdfSAP FOR CONTRACT MANUFACTURING.pdf
SAP FOR CONTRACT MANUFACTURING.pdfVirendra Rai, PMP
13 views2 slides
.NET Developer Conference 2023 - .NET Microservices mit Dapr – zu viel Abstra... by
.NET Developer Conference 2023 - .NET Microservices mit Dapr – zu viel Abstra....NET Developer Conference 2023 - .NET Microservices mit Dapr – zu viel Abstra...
.NET Developer Conference 2023 - .NET Microservices mit Dapr – zu viel Abstra...Marc Müller
40 views62 slides
SAP FOR TYRE INDUSTRY.pdf by
SAP FOR TYRE INDUSTRY.pdfSAP FOR TYRE INDUSTRY.pdf
SAP FOR TYRE INDUSTRY.pdfVirendra Rai, PMP
24 views3 slides
Team Transformation Tactics for Holistic Testing and Quality (Japan Symposium... by
Team Transformation Tactics for Holistic Testing and Quality (Japan Symposium...Team Transformation Tactics for Holistic Testing and Quality (Japan Symposium...
Team Transformation Tactics for Holistic Testing and Quality (Japan Symposium...Lisi Hocke
35 views124 slides

Recently uploaded(20)

Fleet Management Software in India by Fleetable
Fleet Management Software in India Fleet Management Software in India
Fleet Management Software in India
Fleetable11 views
Ports-and-Adapters Architecture for Embedded HMI by Burkhard Stubert
Ports-and-Adapters Architecture for Embedded HMIPorts-and-Adapters Architecture for Embedded HMI
Ports-and-Adapters Architecture for Embedded HMI
Burkhard Stubert21 views
.NET Developer Conference 2023 - .NET Microservices mit Dapr – zu viel Abstra... by Marc Müller
.NET Developer Conference 2023 - .NET Microservices mit Dapr – zu viel Abstra....NET Developer Conference 2023 - .NET Microservices mit Dapr – zu viel Abstra...
.NET Developer Conference 2023 - .NET Microservices mit Dapr – zu viel Abstra...
Marc Müller40 views
Team Transformation Tactics for Holistic Testing and Quality (Japan Symposium... by Lisi Hocke
Team Transformation Tactics for Holistic Testing and Quality (Japan Symposium...Team Transformation Tactics for Holistic Testing and Quality (Japan Symposium...
Team Transformation Tactics for Holistic Testing and Quality (Japan Symposium...
Lisi Hocke35 views
Myths and Facts About Hospice Care: Busting Common Misconceptions by Care Coordinations
Myths and Facts About Hospice Care: Busting Common MisconceptionsMyths and Facts About Hospice Care: Busting Common Misconceptions
Myths and Facts About Hospice Care: Busting Common Misconceptions
Unlocking the Power of AI in Product Management - A Comprehensive Guide for P... by NimaTorabi2
Unlocking the Power of AI in Product Management - A Comprehensive Guide for P...Unlocking the Power of AI in Product Management - A Comprehensive Guide for P...
Unlocking the Power of AI in Product Management - A Comprehensive Guide for P...
NimaTorabi212 views
2023-November-Schneider Electric-Meetup-BCN Admin Group.pptx by animuscrm
2023-November-Schneider Electric-Meetup-BCN Admin Group.pptx2023-November-Schneider Electric-Meetup-BCN Admin Group.pptx
2023-November-Schneider Electric-Meetup-BCN Admin Group.pptx
animuscrm15 views
DSD-INT 2023 Process-based modelling of salt marsh development coupling Delft... by Deltares
DSD-INT 2023 Process-based modelling of salt marsh development coupling Delft...DSD-INT 2023 Process-based modelling of salt marsh development coupling Delft...
DSD-INT 2023 Process-based modelling of salt marsh development coupling Delft...
Deltares7 views
AI and Ml presentation .pptx by FayazAli87
AI and Ml presentation .pptxAI and Ml presentation .pptx
AI and Ml presentation .pptx
FayazAli8712 views
BushraDBR: An Automatic Approach to Retrieving Duplicate Bug Reports by Ra'Fat Al-Msie'deen
BushraDBR: An Automatic Approach to Retrieving Duplicate Bug ReportsBushraDBR: An Automatic Approach to Retrieving Duplicate Bug Reports
BushraDBR: An Automatic Approach to Retrieving Duplicate Bug Reports
360 graden fabriek by info33492
360 graden fabriek360 graden fabriek
360 graden fabriek
info33492122 views
Generic or specific? Making sensible software design decisions by Bert Jan Schrijver
Generic or specific? Making sensible software design decisionsGeneric or specific? Making sensible software design decisions
Generic or specific? Making sensible software design decisions
Airline Booking Software by SharmiMehta
Airline Booking SoftwareAirline Booking Software
Airline Booking Software
SharmiMehta6 views
DSD-INT 2023 Exploring flash flood hazard reduction in arid regions using a h... by Deltares
DSD-INT 2023 Exploring flash flood hazard reduction in arid regions using a h...DSD-INT 2023 Exploring flash flood hazard reduction in arid regions using a h...
DSD-INT 2023 Exploring flash flood hazard reduction in arid regions using a h...
Deltares9 views
Copilot Prompting Toolkit_All Resources.pdf by Riccardo Zamana
Copilot Prompting Toolkit_All Resources.pdfCopilot Prompting Toolkit_All Resources.pdf
Copilot Prompting Toolkit_All Resources.pdf
Riccardo Zamana10 views
Unmasking the Dark Art of Vectored Exception Handling: Bypassing XDR and EDR ... by Donato Onofri
Unmasking the Dark Art of Vectored Exception Handling: Bypassing XDR and EDR ...Unmasking the Dark Art of Vectored Exception Handling: Bypassing XDR and EDR ...
Unmasking the Dark Art of Vectored Exception Handling: Bypassing XDR and EDR ...
Donato Onofri860 views
Dev-HRE-Ops - Addressing the _Last Mile DevOps Challenge_ in Highly Regulated... by TomHalpin9
Dev-HRE-Ops - Addressing the _Last Mile DevOps Challenge_ in Highly Regulated...Dev-HRE-Ops - Addressing the _Last Mile DevOps Challenge_ in Highly Regulated...
Dev-HRE-Ops - Addressing the _Last Mile DevOps Challenge_ in Highly Regulated...
TomHalpin96 views

Chasing the optimizer

  • 2. Agenda • Optimizer – Introduction – Query Blocks – Physical Optimization – Logical Optimization – Common Transformations • Real-life example 2
  • 3. Trivia • How many joins evaluated for this SQL? 12.1 SELECT e1.email, jh.job_id FROM employees e1, job_history jh WHERE e1.employee_id = jh.employee_id AND jh.start_date > '01-JAN-01' AND e1.salary > (SELECT /*+ QB_NAME(SQ1) */ AVG(e2.salary) FROM employees e2 WHERE e1.department_id = e2.department_id) AND e1.department_id IN (SELECT /*+ QB_NAME(SQ2) */ d.department_id FROM departments d, locations l WHERE d.location_id = l.location_id AND l.country_id = 'US') grep -c 'Join order[' cdb1_ora_5541.trc 198 3
  • 4. A day in the life of the optimizer • Generate an optimal plan • Multiple challenges – Partial knowledge of data and query (stats/binds) – Short amount of time (ms) – Use as little CPU and memory as possible 4
  • 6. How to make it out alive? • Play it smart! • Two phases optimization – Logical and Physical • Logical phase transforms SQL – Trying to find potentially better forms – Open the door to better plans • Physical phase – Identify optimal access to objects involved 6
  • 8. Query Block • SQL can be complex – Made of smaller SQLs (each is a QB) – QBs correlate to each other • QB is optimizer unit of optimization – Logical opt “reshapes” query blocks – Physical opt find optimal way to execute each QB 8
  • 10. How many QBs? create table t1 as select * from dba_objects; create table t2 as select * from dba_objects; select owner, object_name from t1 where last_ddl_time > (select median(last_ddl_time) from t2 where t1.owner = t2.owner); 10 Registered qb: SEL$1 0x71b6df90 (PARSER) --------------------- QUERY BLOCK SIGNATURE --------------------- signature (): qb_name=SEL$1 nbfros=1 flg=0 fro(0): flg=4 objn=24765 hint_alias="T1"@"SEL$1" Registered qb: SEL$2 0x71b5e260 (PARSER) --------------------- QUERY BLOCK SIGNATURE --------------------- signature (): qb_name=SEL$2 nbfros=1 flg=0 fro(0): flg=4 objn=24766 hint_alias="T2"@"SEL$2"
  • 11. How many QBs? create table t1 as select * from dba_objects; create table t2 as select * from dba_objects; select * from t1 union all select * from t2; 11 Registered qb: SEL$1 0x719d65b8 (PARSER) --------------------- QUERY BLOCK SIGNATURE --------------------- signature (): qb_name=SEL$1 nbfros=1 flg=0 fro(0): flg=4 objn=24765 hint_alias="T1"@"SEL$1" Registered qb: SET$1 0x719c6610 (PARSER) --------------------- QUERY BLOCK SIGNATURE --------------------- signature (): qb_name=SET$1 nbfros=1 flg=0 fro(0): flg=0 objn=0 hint_alias="NULL_HALIAS"@"SET$1" Registered qb: SEL$2 0x719c6c68 (PARSER) --------------------- QUERY BLOCK SIGNATURE --------------------- signature (): qb_name=SEL$2 nbfros=1 flg=0 fro(0): flg=4 objn=24766 hint_alias="T2"@"SEL$2"
  • 12. Physical optimizer • Been around for a long time – The one to always get blamed (*) – Lots of literature about it • Goal: find optimal exec plan for QB – The “calculator” part of the optimizer – Identify driver table and access method for it – Identify optimal join order and join methods 12
  • 13. How does it look in 10053? • Roughly between these two text blocks --------------------- QUERY BLOCK SIGNATURE --------------------- signature (optimizer): qb_name=SEL$683B0107 nbfros=1 flg=0 fro(0): flg=0 objn=24766 hint_alias="T2"@"SEL$2” ----------------------------- SYSTEM STATISTICS INFORMATION ..... ….. ..... Final cost for query block SEL$683B0107 (#2) - All Rows Plan: Best join order: 1 Cost: 80.6652 Degree: 1 Card: 20353.0000 Bytes: 284942 Resc: 80.6652 Resc_io: 79.0000 Resc_cpu: 52711834 Resp: 80.6652 Resp_io: 79.0000 Resc_cpu: 52711834 13
  • 14. How does it look in 10053? (2) • Statistics report objects in QB • Best access path per object identified – At this stage the objects are disconnected BASE STATISTICAL INFORMATION *********************** Table Stats:: Table: T2 Alias: T2 #Rows: 20353 #Blks: 285 AvgRowLen: 90.00 ChainCnt: 0.00 Column (#1): OWNER( AvgLen: 6 NDV: 14 Nulls: 0 Density: 0.071429 Access path analysis for T2 *************************************** SINGLE TABLE ACCESS PATH Single Table Cardinality Estimation for T2[T2] Table: T2 Alias: T2 Card: Original: 20353.000000 Rounded: 20353 Computed: 20353.00 Non Adjusted: 20353.00 Access Path: TableScan Cost: 79.25 Resp: 79.25 Degree: 0 Cost_io: 79.00 Cost_cpu: 7931980 Resp_io: 79.00 Resp_cpu: 7931980 Best:: AccessPath: TableScan Cost: 79.25 Degree: 1 Resp: 79.25 Card: 20353.00 Bytes: 0 14
  • 16. Logical Optimizer • The “brain” of the optimizer • Applies transformations to SQL – Multiple transformations per QB – MUST keep semantics of query • Use two approaches – Heuristic-based trans -> always beneficial – Cost-based trans -> “it depends” beneficial 16
  • 18. Heuristic-based transformations • Apply those changes always beneficial – Filter and project as soon as possible – Eliminate redundant operations – Reduce number of QBs (merge) • Less QBs means more permutations per QB • Applied before cost-based – And sometime after cost-based too 18
  • 19. Cost-based transformations • Require costing to determine if beneficial – Physical optimizer costs with trans ON/OFF, cheapest wins • CBQT Framework – Orchestrates multiple transformations • Interleaved (one on top of another) • Juxtaposed (either one or another) – Allows new transformations to be plugged in – Time savvy (limit search space, annotations, etc) 19
  • 20. How many transformations? • A LOT! • Can change plan very little and/or very much • Dependent on coding style • Some are very common – Subquery unnesting (heuristic and cost-based) – View merging (heuristic and cost-based) – Join Predicate Push Down (mostly cost-based today) 20
  • 21. Subquery Unnesting select * from t1 where object_id in ( select object_id from t2); ----------------------------------- | Id | Operation | Name | ----------------------------------- | 0 | SELECT STATEMENT | | |* 1 | FILTER | | | 2 | TABLE ACCESS FULL| T1 | |* 3 | TABLE ACCESS FULL| T2 | 21 select * from t1, t2 where t1.object_id s= t2.object_id; ------------------------------------- | Id | Operation | Name | ------------------------------------- | 0 | SELECT STATEMENT | | |* 1 | HASH JOIN RIGHT SEMI| | | 2 | TABLE ACCESS FULL | T2 | | 3 | TABLE ACCESS FULL | T1 | Easy to spot FILTER operation is gone
  • 22. View Merging select t1.* from t1, (select object_id from t2) t2 where t1.object_id = t2.object_id; ------------------------------------ | Id | Operation | Name | ------------------------------------ | 0 | SELECT STATEMENT | | |* 1 | HASH JOIN | | | 2 | VIEW | | | 3 | TABLE ACCESS FULL| T2 | | 4 | TABLE ACCESS FULL | T1 | 22 select t1.* from t1, t2 where t1.object_id = t2.object_id; --------------------------------------+ | Id | Operation | Name | --------------------------------------+ | 0 | SELECT STATEMENT | | | 1 | HASH JOIN | | | 2 | TABLE ACCESS FULL | T2 | | 3 | TABLE ACCESS FULL | T1 | Easy to spot VIEW operation is gone
  • 23. Join Predicate Push Down select t1.* from t1, (select object_id from t2) t2 where t1.object_id = t2.object_id(+); -------------------------------------- | Id | Operation | Name | -------------------------------------- | 0 | SELECT STATEMENT | | |* 1 | HASH JOIN RIGHT OUTER| | | 2 | VIEW | | | 3 | TABLE ACCESS FULL | T2 | | 4 | TABLE ACCESS FULL | T1 | 23 select t1.* from t1, (select object_id from t2 where t1.object_id = t2.object_id(+)) t2 ---------------------------------------- | Id | Operation | Name | ---------------------------------------- | 0 | SELECT STATEMENT | | | 1 | NESTED LOOPS OUTER | | | 2 | TABLE ACCESS FULL | T1 | | 3 | VIEW PUSHED PREDICATE | | |* 4 | TABLE ACCESS FULL | T2 | Easy to spot VIEW operation shows PUSH occurred
  • 24. So far we learned • CBO life is tough J • SQL is split and optimized in chunks (QBs) • Logical Optim modifies QBs (1+) • Physical Optim costs changed QBs (1) • Cheapest plan (Logical + Physical) wins • Some transformations are common • It all sounds pretty simple, right? 24
  • 25. How does it look in 10053? • This is where things get tricky – No way out, 10053 is source of truth • Average SQL produces 100k/250k+ rows trace – Trace not designed to be summarized – Supposed to be READ by you – Very very verbose (and sometimes not enough L) • We need a plan! • Easier to show with an example 25
  • 26. Let the fun begin Objects from HR sample schema SELECT e1.email, jh.job_id FROM employees e1, job_history jh WHERE e1.employee_id = jh.employee_id AND jh.start_date > '01-JAN-01' AND e1.salary > (SELECT AVG(e2.salary) FROM employees e2 WHERE e1.department_id = e2.department_id) AND e1.department_id IN (SELECT d.department_id FROM departments d, locations l WHERE d.location_id = l.location_id AND l.country_id = 'US’) 26
  • 27. This is the final plan ------------------------------------------------------------------------- | Id | Operation | Name | ------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | |* 1 | FILTER | | |* 2 | HASH JOIN | | |* 3 | TABLE ACCESS BY INDEX ROWID BATCHED| JOB_HISTORY | |* 4 | INDEX SKIP SCAN | JHIST_EMP_ID_ST_DATE_PK | | 5 | TABLE ACCESS FULL | EMPLOYEES | | 6 | NESTED LOOPS | | | 7 | TABLE ACCESS BY INDEX ROWID | DEPARTMENTS | |* 8 | INDEX UNIQUE SCAN | DEPT_ID_PK | |* 9 | TABLE ACCESS BY INDEX ROWID | LOCATIONS | |* 10 | INDEX UNIQUE SCAN | LOC_ID_PK | | 11 | SORT AGGREGATE | | | 12 | TABLE ACCESS BY INDEX ROWID BATCHED| EMPLOYEES | |* 13 | INDEX RANGE SCAN | EMP_DEPARTMENT_IX | ------------------------------------------------------------------------- 27
  • 28. No, it’s this one --------------------------------------------------------------------------+ | Id | Operation | Name | --------------------------------------------------------------------------+ | 0 | SELECT STATEMENT | | | 1 | NESTED LOOPS | | | 2 | NESTED LOOPS SEMI | | | 3 | NESTED LOOPS | | | 4 | TABLE ACCESS BY INDEX ROWID BATCHED | JOB_HISTORY | | 5 | INDEX SKIP SCAN | JHIST_EMP_ID_ST_DATE_PK| | 6 | TABLE ACCESS BY INDEX ROWID | EMPLOYEES | | 7 | INDEX UNIQUE SCAN | EMP_EMP_ID_PK | | 8 | VIEW PUSHED PREDICATE | VW_NSO_2 | | 9 | NESTED LOOPS | | | 10 | TABLE ACCESS BY INDEX ROWID | DEPARTMENTS | | 11 | INDEX UNIQUE SCAN | DEPT_ID_PK | | 12 | TABLE ACCESS BY INDEX ROWID | LOCATIONS | | 13 | INDEX UNIQUE SCAN | LOC_ID_PK | | 14 | VIEW PUSHED PREDICATE | VW_SQ_1 | | 15 | FILTER | | | 16 | SORT AGGREGATE | | | 17 | TABLE ACCESS BY INDEX ROWID BATCHED | EMPLOYEES | | 18 | INDEX RANGE SCAN | EMP_DEPARTMENT_IX | --------------------------------------------------------------------------+ 28
  • 29. Sorry, it’s this one --------------------------------------------------------------------------- | Id | Operation | Name | --------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | |* 1 | FILTER | | | 2 | NESTED LOOPS SEMI | | | 3 | NESTED LOOPS | | |* 4 | TABLE ACCESS BY INDEX ROWID BATCHED | JOB_HISTORY | |* 5 | INDEX SKIP SCAN | JHIST_EMP_ID_ST_DATE_PK | | 6 | TABLE ACCESS BY INDEX ROWID | EMPLOYEES | |* 7 | INDEX UNIQUE SCAN | EMP_EMP_ID_PK | | 8 | VIEW PUSHED PREDICATE | VW_NSO_1 | | 9 | NESTED LOOPS | | | 10 | TABLE ACCESS BY INDEX ROWID | DEPARTMENTS | |* 11 | INDEX UNIQUE SCAN | DEPT_ID_PK | |* 12 | TABLE ACCESS BY INDEX ROWID BATCHED| LOCATIONS | |* 13 | INDEX RANGE SCAN | LOC_COUNTRY_IX | | 14 | SORT AGGREGATE | | | 15 | TABLE ACCESS BY INDEX ROWID BATCHED | EMPLOYEES | |* 16 | INDEX RANGE SCAN | EMP_DEPARTMENT_IX | --------------------------------------------------------------------------- 29
  • 30. Ops, it’s this one, I swear! ------------------------------------------------------------------------------ | Id | Operation | Name | ------------------------------------------------------------------------------ | 0 | SELECT STATEMENT | | |* 1 | FILTER | | | 2 | NESTED LOOPS | | | 3 | NESTED LOOPS | | | 4 | NESTED LOOPS | | | 5 | VIEW | VW_NSO_1 | | 6 | HASH UNIQUE | | | 7 | NESTED LOOPS SEMI | | | 8 | VIEW | index$_join$_004 | |* 9 | HASH JOIN | | | 10 | INDEX FAST FULL SCAN | DEPT_ID_PK | | 11 | INDEX FAST FULL SCAN | DEPT_LOCATION_IX | |* 12 | TABLE ACCESS BY INDEX ROWID BATCHED| LOCATIONS | |* 13 | INDEX RANGE SCAN | LOC_COUNTRY_IX | | 14 | TABLE ACCESS BY INDEX ROWID BATCHED | EMPLOYEES | |* 15 | INDEX RANGE SCAN | EMP_DEPARTMENT_IX | |* 16 | INDEX RANGE SCAN | JHIST_EMP_ID_ST_DATE_PK | |* 17 | TABLE ACCESS BY INDEX ROWID | JOB_HISTORY | | 18 | SORT AGGREGATE | | | 19 | TABLE ACCESS BY INDEX ROWID BATCHED | EMPLOYEES | |* 20 | INDEX RANGE SCAN | EMP_DEPARTMENT_IX | ------------------------------------------------------------------------------ 30
  • 32. Starting point Objects from HR sample schema SELECT e1.email, jh.job_id FROM employees e1, job_history jh WHERE e1.employee_id = jh.employee_id AND jh.start_date > '01-JAN-01' AND e1.salary > (SELECT AVG(e2.salary) FROM employees e2 WHERE e1.department_id = e2.department_id) AND e1.department_id IN (SELECT d.department_id FROM departments d, locations l WHERE d.location_id = l.location_id AND l.country_id = 'US’) 45k 10053 trace file 32
  • 33. How many QBs? Registered qb: SEL$1 0x4cf0e098 (PARSER) signature (): qb_name=SEL$1 nbfros=2 flg=0 fro(0): flg=4 objn=96089 hint_alias="E1"@"SEL$1" fro(1): flg=4 objn=96093 hint_alias="JH"@"SEL$1" Registered qb: SEL$2 0x4cf04f00 (PARSER) signature (): qb_name=SEL$2 nbfros=1 flg=0 fro(0): flg=4 objn=96089 hint_alias="E2"@"SEL$2" Registered qb: SEL$3 0x4cf03f60 (PARSER) signature (): qb_name=SEL$3 nbfros=2 flg=0 fro(0): flg=4 objn=96084 hint_alias="D"@"SEL$3" fro(1): flg=4 objn=96081 hint_alias="L"@"SEL$3” • Think of 3 QBs as 3 pieces of LEGO • Transformed and cost N times 33
  • 34. Which transformations applied? • QB Registry in 10053 tells you the story • All (most) of the transformations for each QB – Includes name of new QBs – Indentation for parent/child relationship – QBs part of best plan have [FINAL] – QBs at the same level are crossroads • Used as a map to chase CBO actions – Enable specific searches in 10053 34
  • 35. Query Block Registry • Each QB dumped with transformations Query Block Registry: SEL$3 0x4c50a700 (PARSER) [FINAL] SEL$8771BF6C 0x0 (SUBQUERY UNNEST SEL$1; SEL$3;) SEL$7C12A527 0x0 (COMPLEX SUBQUERY UNNEST SEL$8771BF6C) SEL$5DB0472E 0x0 (SPLIT/MERGE QUERY BLOCKS SEL$8771BF6C) SEL$2AD7F9D9 0x0 (PUSHED PREDICATE SEL$291F8F59; SEL$8771BF6C; "VW_NSO_11"@"SEL$8771BF6C" 4) SEL$2E20A9F9 0x0 (SUBQUERY UNNEST SEL$7511BFD2; SEL$3; SEL$2;) SEL$CC348667 0x0 (COMPLEX SUBQUERY UNNEST SEL$2E20A9F9) SEL$291F8F59 0x0 (SUBQ INTO VIEW FOR COMPLEX UNNEST SEL$3) SEL$555A942D 0x0 (VIEW MERGE SEL$C149BB3C; SEL$291F8F59) SEL$C149BB3C 0x0 (PROJECTION VIEW FOR CVM SEL$291F8F59) SEL$555A942D 0x0 (VIEW MERGE SEL$C149BB3C; SEL$291F8F59) SEL$2AD7F9D9 0x0 (PUSHED PREDICATE SEL$291F8F59; SEL$8771BF6C; "VW_NSO_11"@"SEL$8771BF6C" 4) SEL$2 0x4c50b6a0 (PARSER) SEL$C772B8D1 0x4c50ff78 (SUBQUERY UNNEST SEL$7511BFD2; SEL$2) [FINAL] SEL$841DDE77 0x0 (VIEW MERGE SEL$C772B8D1; SEL$683B0107) SEL$C6423BE4 0x0 (PUSHED PREDICATE SEL$683B0107; SEL$C772B8D1; "VW_SQ_1"@"SEL$7511BFD2" 4) SEL$2E20A9F9 0x0 (SUBQUERY UNNEST SEL$7511BFD2; SEL$3; SEL$2;) ... SEL$683B0107 0x4c50b6a0 (SUBQ INTO VIEW FOR COMPLEX UNNEST SEL$2) [FINAL] SEL$841DDE77 0x0 (VIEW MERGE SEL$C772B8D1; SEL$683B0107) SEL$C6423BE4 0x0 (PUSHED PREDICATE SEL$683B0107; SEL$C772B8D1; "VW_SQ_1"@"SEL$7511BFD2" 4) SEL$1 0x4c50ff78 (PARSER) SEL$8771BF6C 0x0 (SUBQUERY UNNEST SEL$1; SEL$3;) ... SEL$7511BFD2 0x4c50ff78 (VIEW ADDED SEL$1) SEL$C772B8D1 0x4c50ff78 (SUBQUERY UNNEST SEL$7511BFD2; SEL$2) [FINAL] ... SEL$2E20A9F9 0x0 (SUBQUERY UNNEST SEL$7511BFD2; SEL$3; SEL$2;) ... 35
  • 36. Final plan is ------------------------------------------------------------+-----------------------------------+ | Id | Operation | Name | Rows | Bytes | Cost | Time | ------------------------------------------------------------+-----------------------------------+ | 0 | SELECT STATEMENT | | | | 10 | | | 1 | FILTER | | | | | | | 2 | NESTED LOOPS | | 2 | 148 | 8 | 00:00:01 | | 3 | NESTED LOOPS | | 17 | 148 | 8 | 00:00:01 | | 4 | HASH JOIN | | 17 | 765 | 7 | 00:00:01 | | 5 | VIEW | VW_SQ_1 | 11 | 286 | 4 | 00:00:01 | | 6 | HASH GROUP BY | | 11 | 77 | 4 | 00:00:01 | | 7 | TABLE ACCESS STORAGE FULL | EMPLOYEES | 107 | 749 | 3 | 00:00:01 | | 8 | TABLE ACCESS STORAGE FULL | EMPLOYEES | 107 | 2033 | 3 | 00:00:01 | | 9 | INDEX RANGE SCAN | JHIST_EMPLOYEE_IX| 1 | | 0 | | | 10 | TABLE ACCESS BY INDEX ROWID | JOB_HISTORY | 1 | 29 | 1 | 00:00:01 | | 11 | NESTED LOOPS | | 1 | 13 | 2 | 00:00:01 | | 12 | TABLE ACCESS BY INDEX ROWID | DEPARTMENTS | 1 | 7 | 1 | 00:00:01 | | 13 | INDEX UNIQUE SCAN | DEPT_ID_PK | 1 | | 0 | | | 14 | TABLE ACCESS BY INDEX ROWID | LOCATIONS | 1 | 6 | 1 | 00:00:01 | | 15 | INDEX UNIQUE SCAN | LOC_ID_PK | 1 | | 0 | | ------------------------------------------------------------+-----------------------------------+ 1 - filter( IS NOT NULL) 4 - access("E1"."DEPARTMENT_ID"="ITEM_1") 4 - filter("E1"."SALARY">"AVG(E2.SALARY)") 9 - access("E1"."EMPLOYEE_ID"="JH"."EMPLOYEE_ID") 36 10 - filter(("JH"."START_DATE">'01-JAN-01' AND "END_DATE">'01-JAN-01')) 13 - access("D"."DEPARTMENT_ID"=:B1) 14 - filter("L"."COUNTRY_ID"='US') 15 - access("D"."LOCATION_ID"="L"."LOCATION_ID")
  • 37. How to attack 10053? • Keep it simple • Remember: multiple internal QB trans from A to B • Ignore “noise”, focus on what you seek > wc –l MAURRRO1_ora_119219_test.trc 44612 MAURRRO1_ora_119219_test.trc > grep -nE '^[A-Z]{2,}:|Registe’ MAURRRO1_ora_119219_test.trc | grep -v 'CBRID…' | wc -l 377 • Use physical opt input QB as anchor – Last one before big jump in 10053 – QB represent the valid status 37
  • 39. Ok one step at a time 1930:SU: Unnesting query blocks in query block SEL$1 (#1) that are valid to unnest. 1935:SU: Considering subquery unnest on query block SEL$1 (#1). 1936:SU: Checking validity of unnesting subquery SEL$2 (#3) 1937:SU: Passed validity checks, but requires costing. 1938:SU: Checking validity of unnesting subquery SEL$3 (#2) 1939:SU: Passed validity checks, but requires costing. 1940:SU: Using search type: exhaustive 1941:SU: Starting iteration 1, state space = (2,3) : (1,1) 1945:Registered qb: SEL$683B0107 0x96361e50 (SUBQ INTO VIEW FOR COMPLEX UNNEST SEL$2) 1952:Registered qb: SEL$7511BFD2 0x962788a8 (VIEW ADDED SEL$1) 1962:Registered qb: SEL$291F8F59 0x96276b58 (SUBQ INTO VIEW FOR COMPLEX UNNEST SEL$3) 1970:Registered qb: SEL$2E20A9F9 0x962788a8 (SUBQUERY UNNEST SEL$7511BFD2; SEL$3; SEL$2;) 2002:SU: Costing transformed query. 2003:CBQT: Looking for cost annotations for query block SEL$683B0107, key = SEL$683B0107_00002002_4 2004:CBQT: Could not find stored cost annotations. 2005:CBQT: Looking for cost annotations for query block SEL$291F8F59, key = SEL$291F8F59_00002002_4 2006:CBQT: Could not find stored cost annotations. … 5151:CBQT: Saved costed qb# 3 (SEL$683B0107), key = SEL$683B0107_00002002_4 5152:CBQT: Saved costed qb# 2 (SEL$291F8F59), key = SEL$291F8F59_00002002_4 5153:CBQT: Saved costed qb# 1 (SEL$2E20A9F9), key = SEL$2E20A9F9_00000000_0 39
  • 41. Digging into 10053 • Use the QB name to search for costs 2160 Final cost for query block SEL$683B0107 (#3) - All Rows Plan: 2161 Best join order: 1 2162 Cost: 4.002661 Degree: 1 Card: 107.000000 Bytes: 749.000000 2646 Final cost for query block SEL$291F8F59 (#2) - All Rows Plan: 2647 Best join order: 1 2648 Cost: 3.218206 Degree: 1 Card: 14.000000 Bytes: 182.000000 2683 signature (optimizer): qb_name=SEL$2E20A9F9 nbfros=4 flg=0 2684 fro(0): flg=0 objn=91753 hint_alias="E1"@"SEL$1" 2685 fro(1): flg=0 objn=91757 hint_alias="JH"@"SEL$1" 2686 fro(2): flg=1 objn=0 hint_alias="VW_NSO_2"@"SEL$2E20A9F9" 2687 fro(3): flg=1 objn=0 hint_alias="VW_SQ_1"@"SEL$7511BFD2" … 5140 Final cost for query block SEL$2E20A9F9 (#1) - All Rows Plan: 5141 Best join order: 4 5142 Cost: 11.366818 Degree: 1 Card: 2.000000 Bytes: 174.000000 5151:CBQT: Saved costed qb# 3 (SEL$683B0107), key = SEL$683B0107_00002002_4 5152:CBQT: Saved costed qb# 2 (SEL$291F8F59), key = SEL$291F8F59_00002002_4 5153:CBQT: Saved costed qb# 1 (SEL$2E20A9F9), key = SEL$2E20A9F9_00000000_0 41
  • 43. First interleaved transformation <<skipped interleaved DP>> 8254:SU: Considering interleaved join pred push down 8255:SU: Unnesting subquery query block SEL$2 (#3)Subquery removal for query block SEL$2 (#3) 8258:SU: Transform an ANY subquery to semi-join or distinct. 8259:JPPD: Checking validity of push-down in query block SEL$2E20A9F9 (#1) 8260:JPPD: Checking validity of push-down from query block SEL$2E20A9F9 (#1) to query block SEL$291F8F59 (#2) 8262:JPPD: Passed validity checks 8263:JPPD: Checking validity of push-down from query block SEL$2E20A9F9 (#1) to query block SEL$683B0107 (#3) 8265:JPPD: Passed validity checks 8266:JPPD: JPPD: Pushdown from query block SEL$2E20A9F9 (#1) passed validity checks. 8268:JPPD: Using search type: linear 8269:JPPD: Considering join predicate push-down 8270:JPPD: Starting iteration 1, state space = (2,3) : (0,0) <<copy QB here>> 8286:JPPD: Performing join predicate push-down (no transformation phase) from query block SEL$2E20A9F9 (#1) to query block SEL$291F8F59 (#2) 8288:JPPD: Performing join predicate push-down (no transformation phase) from query block SEL$2E20A9F9 (#1) to query block SEL$683B0107 (#3) 8312:JPPD: Costing transformed query. … 11461:CBQT: Saved costed qb# 3 (SEL$683B0107), key = SEL$683B0107_00042002_4 11462:CBQT: Saved costed qb# 2 (SEL$291F8F59), key = SEL$291F8F59_00042002_4 11463:CBQT: Saved costed qb# 1 (SEL$2E20A9F9), key = SEL$2E20A9F9_00000000_0 43
  • 45. Digging into 10053 • Use the QB name to search for costs 8470 Final cost for query block SEL$683B0107 (#3) - All Rows Plan: 8471 Best join order: 1 8472 Cost: 4.002661 Degree: 1 Card: 107.000000 Bytes: 749.000000 8956 Final cost for query block SEL$291F8F59 (#2) - All Rows Plan: 8957 Best join order: 1 8958 Cost: 3.218206 Degree: 1 Card: 14.000000 Bytes: 182.000000 8993 signature (optimizer): qb_name=SEL$2E20A9F9 nbfros=4 flg=0 8994 fro(0): flg=0 objn=91753 hint_alias="E1"@"SEL$1" 8995 fro(1): flg=0 objn=91757 hint_alias="JH"@"SEL$1" 8996 fro(2): flg=1 objn=0 hint_alias="VW_NSO_6"@"SEL$2E20A9F9" 8997 fro(3): flg=1 objn=0 hint_alias="VW_SQ_5"@"SEL$7511BFD2" … 11450 Final cost for query block SEL$2E20A9F9 (#1) - All Rows Plan: 11451 Best join order: 4 11452 Cost: 11.366818 Degree: 1 Card: 2.000000 Bytes: 174.000000 11461:CBQT: Saved costed qb# 3 (SEL$683B0107), key = SEL$683B0107_00042002_4 11462:CBQT: Saved costed qb# 2 (SEL$291F8F59), key = SEL$291F8F59_00042002_4 11463:CBQT: Saved costed qb# 1 (SEL$2E20A9F9), key = SEL$2E20A9F9_00000000_0 11464:JPPD: Updated best state, Cost = 11.366818 45
  • 46. More JPPD iterations 11465:JPPD: Starting iteration 2, state space = (2,3) : (1,0) 11466:JPPD: Performing join predicate push-down (candidate phase) from query block SEL$2E20A9F9 (#1) to query block SEL$291F8F59 (#2) 11467:JPPD: Pushing predicate "E1"."DEPARTMENT_ID"="VW_NSO_6"."DEPARTMENT_ID" 11469:JPPD: Push dest of pred 0x7fd396030c68 is qb 0x7fd396033fb8:query block SEL$291F8F59 (#2) 11471:JPPD: Performing join predicate push-down (no transformation phase) from query block SEL$2E20A9F9 (#1) to query block SEL$683B0107 (#3) 11503:JPPD: Costing transformed query. 12363:CBQT: Looking for cost annotations for query block SEL$683B0107, key = SEL$683B0107_00002002_4 12364:CBQT: Replaced cost annotations in query block SEL$683B0107. 12365:CBQT: Looking for cost annotations for query block SEL$2AD7F9D9, key = SEL$2AD7F9D9_00082212_4 12366:CBQT: Could not find stored cost annotations. … 13907:CBQT: Saved costed qb# 3 (SEL$683B0107), key = SEL$683B0107_00002002_4 13908:CBQT: Saved costed qb# 1 (SEL$2E20A9F9), key = SEL$2E20A9F9_00100200_0 13909:JPPD: Not update best state, Cost = 13.036576 … 46
  • 48. More JPPD iterations … 13910:JPPD: Starting iteration 3, state space = (2,3) : (0,1) 13952:JPPD: Costing transformed query. 13953:CBQT: Looking for cost annotations for query block SEL$C6423BE4, key = SEL$C6423BE4_00082212_4 13954:CBQT: Could not find stored cost annotations. 13955:CBQT: Looking for cost annotations for query block SEL$291F8F59, key = SEL$291F8F59_00002002_4 13956:CBQT: Replaced cost annotations in query block SEL$291F8F59. … 15338:JPPD: Not update best state, Cost = 28.256163 48
  • 50. Done with JPPD, moving on 15339:JPPD: Will not use JPPD from query block SEL$2E20A9F9 (#1) 15341:SU: Rejected interleaved query. 15342:SU: Finished interleaved join pred push down 15343:SU: Updated best state, Cost = 11.366818 15344:Registered qb: SEL$CC348667 0x962788a8 (COMPLEX SUBQUERY UNNEST SEL$2E20A9F9) 15354:SU: Starting iteration 2, state space = (2,3) : (1,0) 15356:Registered qb: SEL$8771BF6C 0x9607ed38 (SUBQUERY UNNEST SEL$1; SEL$3;) 15390:SU: Costing transformed query. … 16988:SU: Considering interleaved complex view merging 16990:CVM: Considering view merge (candidate phase) in query block SEL$8771BF6C (#1) 16993:CVM: Considering view merge (candidate phase) in query block SEL$291F8F59 (#2) 16996:CVM: CBQT Marking query block SEL$291F8F59 (#2) as valid for CVM. 16997:CVM: Merging complex view SEL$291F8F59 (#2) into SEL$8771BF6C (#1). 17002:Registered qb: SEL$8771BF6C 0x96096420 (COPY SEL$8771BF6C) 17007:Registered qb: SEL$5DB0472E 0x96075e60 (SPLIT/MERGE QUERY BLOCKS SEL$8771BF6C) 17014:Registered qb: SEL$C149BB3C 0x96096420 (PROJECTION VIEW FOR CVM SEL$291F8F59) 17041:Registered qb: SEL$555A942D 0x96096420 (VIEW MERGE SEL$C149BB3C; SEL$291F8F59) 17075:SU: Costing transformed query. … 20976:SU: Interleaved cost better than best so far. 50
  • 51. Flash forward 20977:SU: Finished interleaved complex view merging 20978:SU: Considering interleaved distinct placement … 22396:SU: Rejected interleaved distinct placement. 22397:SU: Finished interleaved distinct placement 22398:SU: Considering interleaved join pred push down … 25631:SU: Rejected interleaved query. 25632:SU: Finished interleaved join pred push down 25633:SU: Not update best state, Cost = 14.206022 … 25643:SU: Starting iteration 3, state space = (2,3) : (0,1) … 27951:SU: Considering interleaved complex view merging … 30186:SU: Considering interleaved distinct placement … 30188:SU: Considering interleaved join pred push down 30200:JPPD: Starting iteration 1, state space = (3) : (0) 32118:JPPD: Updated best state, Cost = 10.133928 32119:JPPD: Starting iteration 2, state space = (3) : (1) 33561:JPPD: Not update best state, Cost = 27.023273 33562:JPPD: Will not use JPPD from query block SEL$C772B8D1 (#1) … 33566:SU: Updated best state, Cost = 10.133928 33567:SU: Starting iteration 4, state space = (2,3) : (0,0) 51
  • 52. Finally the end J 34775:SU: Not update best state, Cost = 17.020791 34776:SU: Will not unnest subquery SEL$3 (#2) 34777:SU: Will unnest subquery SEL$2 (#3) 34778:SU: Reconstructing original query from best state. … 52
  • 53. Summary • Logical optimizer changes QBs • Physical optimizer used to cost changes • QB Registry tracks all those changes – Can be used to find the cost of each trans – Find if trans expected was even considered – Find cost of trans expected vs selected • It’s not hard but it requires practice 53
  • 54. 54
  • 55. Contact Information • http://mauro-pagano.com – Email • mauro.pagano@gmail.com – Download • SQLd360 vYYMM (date) – Pages • SQLd360 55