SlideShare une entreprise Scribd logo
1  sur  61
Télécharger pour lire hors ligne
Shaping the

Optimizer’s

Search-Space
@MarkusWinand
The Optimizer’s Search-Space is Limited
“the query optimizer determines

the most efficient execution plan*”
...most efficient? Out of what?
*http://docs.oracle.com/cd/E16655_01/server.121/e15857/pfgrf_perf_overview.htm#TGDBA94082
The Optimizer’s Search-Space is Limited
The Optimizer...
‣Considers existing indexes only
➡ Other indexes might give even better performance
‣Doesn’t de-obfuscate queries very well
➡ Writing it in simpler terms might improve performance
‣Has built-in limitations
➡ Some theoretically possible plans are never considered
Bring the Best Plan in the Search-Space
... it determines the most efficient
execution plan out of the remaining ones.
Before the optimizer can find the

absolutely best plan we must first

make sure it is within these boundaries.
Two steps to get the absolutely best access path:
1. Maximize data-locality
‣ Plain old B-tree index is the #1 tool for that
‣ Partitions are greatly overrated
‣ Table clusters are slightly underrated
It’s All About Matching Queries to Indexes
2. Write the query to exploit it
‣ Use explicit range conditions
‣ Use top-n based termination
‣ Exploit index order
Thinking
in
Ordered

Sets
Visualizing Indexes as Pyramids
Visualize Simplify
The Order of Multi-Column Indexes
The Order of Multi-Column Indexes
The Order of Multi-Column Indexes
Using Indexes:
Column Order Defines Row-Locality
Example: WHERE	A	>	:a	AND	B	=	:b
Using Indexes:
Column Order Defines Row-Locality
Example: WHERE	A	>	:a	AND	B	=	:b
Using Indexes:
Column Order Defines Row-Locality
Simple-man’s guidelines (best in ~97% of the cases):
‣ Conjunctive equality conditions are king
Column order doesn’t affect data-locality
➡ Put them first into the index and choose the column
order so that other queries can use the index too.
‣ Conjunctive range conditions are tricky
Column order affects data-locality
➡ Put them after the equality columns. If there are
multiple range conditions, put the most-selective first.
Using Indexes:
Column Order Defines Row-Locality
Common mistakes:
‣ Arbitrary column order ☠ (bad)
“Just put all columns from the where-clause in the index”
➡ Works only for all-conjunctive all-equality searches
➡ Doesn’t make the index useful for other queries
‣ Most-selective first ☠ (bad)
“Order the columns according to the selectivity”
➡ Only valid to prioritize among multiple range conditions
Using Indexes:
Finding Bad Index Row-Locality
------------------------------------	
|	Id	|	Operation																			|	
------------------------------------	
|		0	|	SELECT	STATEMENT												|	
|		1	|		TABLE	ACCESS	BY	INDEX	ROWID|	
|*	2	|			INDEX	SKIP	SCAN											|	
------------------------------------	
Predicate	Information:	
------------------------------------	
			2	-	access("B"=20	AND	"A">25)	
							filter("B"=20)
Index on (A, B)
------------------------------------	
|	Id	|	Operation																			|		
------------------------------------	
|		0	|	SELECT	STATEMENT												|		
|		1	|		TABLE	ACCESS	BY	INDEX	ROWID|		
|*	2	|			INDEX	RANGE	SCAN										|		
------------------------------------	
Predicate	Information:	
------------------------------------	
			2	-	access("B"=20	AND	"A">25)	
Index on (B, A)
Most

efficient solution
Most efficient

workaround
‣ Index filter predicates are a “bad smell”
‣ Index Skip Scan is a “bad smell”
‣ Index Fast Full Scan is a “bad smell”
Using Indexes:
Trailing-Columns to Avoid Table-Access
Example: SELECT	C	FROM	X	WHERE	A	>	:a	AND	B	=	:b
Using Indexes:
Trailing-Columns to Avoid Table-Access
Example: SELECT	C	FROM	X	WHERE	A	>	:a	AND	B	=	:b
Using Indexes:
Trailing-Columns to Avoid Table-Access
Add all needed columns to the index to avoid table access.

The so-called index-only scan.
‣ Useful to nullify a bad clustering factor

Consequently, not very useful if
➡ Clustering factor close to the number of table blocks or
➡ Selecting only a few rows
‣ A single non-indexed column breaks it
No matter where it is mentioned (SELECT, ORDER	BY,...)
➡ All or nothing: no benefit from adding some SELECT
columns to the index.
Using Indexes:
Trailing-Columns to Avoid Table-Access
Common mistakes:
‣ Selecting unneeded columns* ☠ (bad)
SELECT * anybody? ORM-tools in use? Hooray!
➡ Adding many columns to many indexes is a no-no.
‣ Pushing too hard ☠ (bad)
➡ Index gets bigger, clustering factor (CF) gets worse
➡ Small benefit for low CF or if selecting a few rows only
➡ You’ll hit the hard limits (32 columns, 6398 bytes@8k)
* http://use-the-index-luke.com/blog/2013-08/its-not-about-the-star-stupid
It’s All About Matching Queries to Indexes
Two steps to get the absolutely best access path:
1. Maximize data-locality
‣ Plain old B-tree index is the #1 tool for that
‣ Partitions are greatly overrated
‣ Table clusters are slightly underrated
2. Write the query to exploit it
‣ Use explicit range conditions
‣ Use top-n based termination
‣ Exploit index order
Thinking
in
Ordered

Sets
✓ ✓
Example:
List yesterday’s orders
CREATE	TABLE	orders	(

				...,

				order_dt	DATE	NOT	NULL,

				...

);	
INSERT	INTO	orders

							(...,	order_dt,	...)

VALUES	(...,	sysdate	,	...);							
100k rows
Evenly distributed

over 4 weeks.
Example:
List yesterday’s orders
1. Maximize data-locality
Example:
List yesterday’s orders
1. Lower bound:

ORDER_DT	>=	TRUNC(sysdate-1)
2. Upper bound:

ORDER_DT	<		TRUNC(sysdate)
2. Write query using explicit range conditions
----------------------------------------------	
|	Id	|	Operation																													|	
----------------------------------------------	
|		0	|	SELECT	STATEMENT																						|	
|*	1	|		FILTER																															|	
|		2	|			TABLE	ACCESS	BY	INDEX	ROWID	BATCHED	|	
|*	3	|				INDEX	RANGE	SCAN																			|	
----------------------------------------------	
Predicate	Information	(identified	by	operation	id):	
---------------------------------------------------	
			1	-	filter(TRUNC(SYSDATE@!)>TRUNC(SYSDATE@!-1))	
			3	-	access("ORDER_DT">=TRUNC(SYSDATE@!-1)	
										AND	"ORDER_DT"<TRUNC(SYSDATE@!))
Example:
List yesterday’s orders
Common anti-pattern:
‣TRUNC(order_dt)=:yesterday	☠ (bad)
This is an “obfuscation” of the actual intention
➡ Requires function-based index

CREATE	INDEX	…	(TRUNC(order_dt));
➡ Doesn’t support ordering by order_dt

WHERE	TRUNC(order_dt)	=	:yesterday

ORDER	BY	order_dt	DESC;
Index

not ordered by that
--------------------------------------	
|	Id	|	Operation																					|	
--------------------------------------	
|		0	|	SELECT	STATEMENT														|	
|*	1	|		FILTER																							|	
|		2	|			TABLE	ACCESS	BY	INDEX	ROWID	|	
|*	3	|				INDEX	RANGE	SCAN	DESCENDING|	
--------------------------------------	
Predicate	Information	(identified	by	operation	id):	
---------------------------------------------------	
			1	-	filter(TRUNC(SYSDATE@!)>TRUNC(SYSDATE@!-1))	
			3	-	access("ORDER_DT"<TRUNC(SYSDATE@!)	
										AND	"ORDER_DT">=TRUNC(SYSDATE@!-1))	
Example:
List yesterday’s orders reverse chronologically
1. Lower & upper bounds:

ORDER_DT	>=	TRUNC(sysdate-1)

ORDER_DT	<		TRUNC(sysdate)	
2. Order

ORDER	BY	ORDER_DT	DESC

2. Write query - exploit index order
--------------------------------------	
|	Id	|	Operation																					|	
--------------------------------------	
|		0	|	SELECT	STATEMENT														|	
|*	1	|		FILTER																							|	
|		2	|			TABLE	ACCESS	BY	INDEX	ROWID	|	
|*	3	|				INDEX	RANGE	SCAN	DESCENDING|	
--------------------------------------	
Predicate	Information	(identified	by	operation	id):	
---------------------------------------------------	
			1	-	filter(TRUNC(SYSDATE@!)>TRUNC(SYSDATE@!-1))	
			3	-	access("ORDER_DT"<TRUNC(SYSDATE@!)	
										AND	"ORDER_DT">=TRUNC(SYSDATE@!-1))	
Example:
List yesterday’s orders reverse chronologically
2. Write query - exploit index order
1. Lower & upper bounds:

		TRUNC(ORDER_DT) 

=	TRUNC(sysdate)-1	
2. Order

ORDER	BY	ORDER_DT	DESC

Example:
List yesterday’s orders reverse chronologically
2. Write query - exploit index order
----------------------------------------------	
|	Id	|	Operation																													|		
----------------------------------------------	
|		0	|	SELECT	STATEMENT																						|				
|		1	|		SORT	ORDER	BY																								|				
|		2	|			TABLE	ACCESS	BY	INDEX	ROWID	BATCHED	|				
|*	3	|				INDEX	RANGE	SCAN																			|	
----------------------------------------------	
Predicate	Information	(identified	by	operation	id):	
---------------------------------------------------	
			3	-	access("ORDERS"."SYS_NC00004$"=TRUNC(SYSDATE@!-1))	
   Tradeoff:

  CPU

 Memory

IO

1. Lower & upper bounds:

		TRUNC(ORDER_DT) 

=	TRUNC(sysdate)-1	
2. Order

ORDER	BY	ORDER_DT	DESC

Example:
List orders from last 24 hours
1. Data-locality for the TRUNC variant
* http://www.sqlfail.com/2014/05/05/oracle-can-now-use-function-based-indexes-in-queries-without-functions/
2. Write query using explicit range conditions
Example:
List orders from last 24 hours
-------------------------------------------------	
|	Id	|	Operation																																|		
-------------------------------------------------	
|		0	|	SELECT	STATEMENT																									|		
|*	1	|		TABLE	ACCESS	BY	INDEX	ROWID	BATCHED					|		
|*	2	|			INDEX	RANGE	SCAN	on	TRUNC(ORDER_DT)				|		
-------------------------------------------------	
Predicate	Information	(identified	by	operation	id):	
---------------------------------------------------	
			1	-	filter("ORDER_DT">SYSDATE@!-1)	
			2	-	access("ORDERS"."SYS_NC00004$">=TRUNC(SYSDATE@!-1))	
2. Upper bound: none (unbounded)
1. Lower bound:

ORDER_DT	>	sysdate	-	1
To use FBI Oracle adds (since 11.2.0.2*)

TRUNC(ORDER_DT)>=TRUNC(sysdate-1)
* http://www.sqlfail.com/2014/05/05/oracle-can-now-use-function-based-indexes-in-queries-without-functions/
Example:
List orders from last 24 hours
1. Maximize data-locality using straight index
Example:
List orders from last 24 hours
2. Write query using explicit range conditions
1. Lower bound:

ORDER_DT	>	sysdate	-	1	
2. Upper bound: none (unbounded)
--------------------------------------------	
|	Id	|	Operation																											|		
--------------------------------------------	
|		0	|	SELECT	STATEMENT																				|		
|		1	|		TABLE	ACCESS	BY	INDEX	ROWID	BATCHED|		
|*	2	|			INDEX	RANGE	SCAN																		|		
--------------------------------------------	
Predicate	Information:	
----------------------	
			2	-	access("ORDER_DT">SYSDATE@!-1)
Example:
List orders from last 24 hours
--------------------------------------------	
|	Id	|	Operation																											|		
--------------------------------------------	
|		0	|	SELECT	STATEMENT																				|		
|		1	|		TABLE	ACCESS	BY	INDEX	ROWID	BATCHED|		
|*	2	|			INDEX	RANGE	SCAN																		|		
--------------------------------------------	
Predicate	Information:	
----------------------	
			2	-	access("ORDER_DT">SYSDATE@!-1)	
--------------------------------------------	
|	Id	|	Operation																											|		
--------------------------------------------	
|		0	|	SELECT	STATEMENT																				|		
|*	1	|		TABLE	ACCESS	BY	INDEX	ROWID	BATCHED|		
|*	2	|			INDEX	RANGE	SCAN																		|		
--------------------------------------------	
Predicate	Information:	
----------------------	
			1	-	filter("ORDER_DT">SYSDATE@!-1)	
			2	-	access("ORDERS"."SYS_NC00004$">=TRUNC(SYSDATE@!-1))	
  Most

 efficient
solution
  Most

 efficient

workaround
It’s All About Matching Queries to Indexes
Two steps to get the absolutely best access path:
1. Maximize data-locality
‣ Plain old B-tree index is the #1 tool for that
‣ Partitions are greatly overrated
‣ Table clusters are slightly underrated
2. Write the query to exploit it
‣ Use explicit range conditions
‣ Use top-n based termination
‣ Exploit index order
Thinking
in
Ordered

Sets
✓
✓
✓
✓
Example:
List 10 Most Recent Orders
1. Maximize data-locality
Example:
List 10 Most Recent Orders
2. Write query using explicit range conditions
1. Lower bound...? After 10 rows...???	
2. Upper bound? sysdate? Unbounded!
Example:
List 10 Most Recent Orders
1. Lower bound...? After 10 rows...???	
2. Upper bound? sysdate? Unbounded!
2. Write query using top-n based termination
3. Start with: most recent

ORDER	BY	ORDER_DT	DESC
4. Stop after: 10 rows

FETCH	FIRST	10	ROWS	ONLY (since 12c)
Example:
List 10 Most Recent Orders
2. Write query using top-n based termination
3. Start with: most recent

ORDER	BY	ORDER_DT	DESC
4. Stop after: 10 rows

FETCH	FIRST	10	ROWS	ONLY (since 12c)
----------------------------------------------------------	
|	Id		|	Operation																					|	A-Rows	|	Buffers	|	
----------------------------------------------------------	
|			0	|	SELECT	STATEMENT														|					10	|							8	|							
|*		1	|		VIEW																									|					10	|							8	|							
|*		2	|			WINDOW	NOSORT	STOPKEY							|					10	|							8	|							
|			3	|				TABLE	ACCESS	BY	INDEX	ROWID|					11	|							8	|							
|			4	|					INDEX	FULL	SCAN	DESCENDING|					11	|							3	|							
----------------------------------------------------------	
Predicate	Information	(identified	by	operation	id):	
---------------------------------------------------	
	1	-	filter("from$_subquery$_002"."rowlimit_$$_rownumber"<=10)	
	2	-	filter(ROW_NUMBER()	OVER	(ORDER	BY	ORDER_DT	DESC)<=10)	ROW_NUMBER()	OVER	(ORDER	BY	ORDER_DT	DESC)<=10




								SELECT	orders.*

													,	ROW_NUMBER()	OVER	(

																			ORDER	BY	order_dt	DESC

															)	rn

										FROM	orders

							
Window-Functions for Top-N Termination
SELECT	*

		FROM	(

								SELECT	orders.*

													,	ROW_NUMBER()	OVER	(

																			ORDER	BY	order_dt	DESC

															)	rn

										FROM	orders

							)

	WHERE	rn	<=	10

	ORDER	BY	order_dt	DESC;
Window-Functions for Top-N Termination
Select 10 rows
Window-Functions for Top-N Termination
SELECT	*

		FROM	(

								SELECT	orders.*

													,	DENSE_RANK()	OVER	(

																			ORDER	BY	TRUNC(order_dt)	DESC

															)	rn

										FROM	orders

							)

	WHERE	rn	<=	1

	ORDER	BY	order_dt	DESC;
Select 1 group
Window-Functions for Top-N Termination
SELECT	*

		FROM	(

								SELECT	orders.*

													,	DENSE_RANK()	OVER	(

																			ORDER	BY	TRUNC(order_dt)	DESC

															)	rn

										FROM	orders

							)

	WHERE	rn	<=	1

	ORDER	BY	order_dt	DESC;
Useful to

abort on edges
Window-Functions for Top-N Termination
SELECT	*

		FROM	(

								SELECT	orders.*

													,	DENSE_RANK()	OVER	(

																			ORDER	BY	TRUNC(order_dt)	DESC

															)	rn

										FROM	orders

							)

	WHERE	rn	<=	1

	ORDER	BY	order_dt	DESC;
---------------------------------------------------------------------------	
|	Id	|	Operation																						|	E-Rows	|	A-Rows	|	Buffers	|	Reads	|	
---------------------------------------------------------------------------	
|		0	|	SELECT	STATEMENT															|								|			2057	|					695	|			695	|	
|		1	|		SORT	ORDER	BY																	|				100K|			2057	|					695	|			695	|	
|*	2	|			VIEW																									|				100K|			2057	|					695	|			695	|	
|*	3	|				WINDOW	NOSORT	STOPKEY							|				100K|			2057	|					695	|			695	|	
|		4	|					TABLE	ACCESS	BY	INDEX	ROWID|				100K|			2058	|					695	|			695	|	
|		5	|						INDEX	FULL	SCAN	DESCENDING|				100K|			2058	|							8	|					8	|	
---------------------------------------------------------------------------	
DENSE_RANK
Window-Functions for Top-N Termination
SELECT	*

		FROM	orders

	WHERE	TRUNC(order_dt)

							=	(SELECT	TRUNC(MAX(order_dt))

												FROM	orders

									)

	ORDER	BY	order_dt	;
---------------------------------------------------------------------------	
|	Id	|	Operation																						|	E-Rows	|	A-Rows	|	Buffers	|	Reads	|	
---------------------------------------------------------------------------	
|		0	|	SELECT	STATEMENT															|								|			2057	|					695	|			695	|	
|		1	|		SORT	ORDER	BY																	|				100K|			2057	|					695	|			695	|	
|*	2	|			VIEW																									|				100K|			2057	|					695	|			695	|	
|*	3	|				WINDOW	NOSORT	STOPKEY							|				100K|			2057	|					695	|			695	|	
|		4	|					TABLE	ACCESS	BY	INDEX	ROWID|				100K|			2058	|					695	|			695	|	
|		5	|						INDEX	FULL	SCAN	DESCENDING|				100K|			2058	|							8	|					8	|	
---------------------------------------------------------------------------	
DENSE_RANK
Window-Functions for Top-N Termination
---------------------------------------------------------------------------------	
|	Id	|	Operation																												|	E-Rows	|	A-Rows	|	Buffers	|	Reads	|	
---------------------------------------------------------------------------------	
|		0	|	SELECT	STATEMENT																					|								|			2057	|				1038	|			694	|	
|		1	|		SORT	ORDER	BY																							|			3448	|			2057	|				1038	|			694	|	
|		2	|			TABLE	ACCESS	BY	INDEX	ROWID	BATCHED|			3448	|			2057	|				1038	|			694	|	
|*	3	|				INDEX	RANGE	SCAN																		|			3448	|			2057	|						10	|					8	|	
|		4	|					SORT	AGGREGATE																			|						1	|						1	|							2	|					2	|	
|		5	|						INDEX	FULL	SCAN	(MIN/MAX)							|						1	|						1	|							2	|					2	|	
---------------------------------------------------------------------------------	
---------------------------------------------------------------------------	
|	Id	|	Operation																						|	E-Rows	|	A-Rows	|	Buffers	|	Reads	|	
---------------------------------------------------------------------------	
|		0	|	SELECT	STATEMENT															|								|			2057	|					695	|			695	|	
|		1	|		SORT	ORDER	BY																	|				100K|			2057	|					695	|			695	|	
|*	2	|			VIEW																									|				100K|			2057	|					695	|			695	|	
|*	3	|				WINDOW	NOSORT	STOPKEY							|				100K|			2057	|					695	|			695	|	
|		4	|					TABLE	ACCESS	BY	INDEX	ROWID|				100K|			2058	|					695	|			695	|	
|		5	|						INDEX	FULL	SCAN	DESCENDING|				100K|			2058	|							8	|					8	|	
---------------------------------------------------------------------------	
DENSE_RANK
SUB-SELECT
Top-N vs. Max()-Subquery
Common mistakes:
‣ Breaking ties with sub-queries ☠ (bad)
WHERE	(a,	b)=	(select	max(a),	max(b)	...)	
➡ max() values coming from different rows...
➡ No rows selected.
‣ Selecting Nth largest ☠ (bad)
WHERE	X	<	(SELECT	MAX()...

												WHERE	X	<	(SELECT	MAX()...))		
WHERE	(N-1)	=	(SELECT	COUNT(DISTINCT(DT))...
It’s All About Matching Queries to Indexes
Two steps to get the absolutely best execution plan:
1. Maximize data-locality
‣ Plain old B-tree index is the #1 tool for that
‣ Partitions are greatly overrated
‣ Table clusters are slightly underrated
2. Write the query to exploit it
‣ Use explicit range conditions
‣ Use top-n based termination
‣ Exploit index order
Thinking
in
Ordered

Sets
✓
✓
✓
✓
✓
1. Maximize data-locality
Example:
List next 10 orders
Example:
List next 10 orders
2. Use explicit range condition & top-n abort
1. Lower bound: unbounded (top-n)
2. Upper bound: where we stopped

WHERE	ORDER_DT	<	:prev_dt
3. ORDER	BY	ORDER_DT	DESC
4. FETCH	FIRST	10	ROWS	ONLY
What about ties?
Explicit range conditions: the general case
Example:
List next 10 orders
Explicit range conditions: the general case
Example:
List next 10 orders
1. Use definite sort order
2. Use Row-Value filter to
remove what we have
seen before (SQL:92)
3. Hit Enter
Explicit range conditions: the general case
Example:
List next 10 orders
Explicit range conditions: the general case
Example:
List next 10 orders
(x,y)	=	(a,b)	
(x,y)	IN	((a,b),(c,d))	
(x,y)	<	(a,b)	
(x,y)	>	(a,b)
✓
✓
✗
✗
Oracle
limitation
Explicit range conditions: the general case
Example:
List next 10 orders
Oracle
limitation
Two semantically

equivalent workarounds:
						X	<=	A	
		AND	NOT(X=A	AND	Y>=B)	
						(X	<	A)	
			OR	(X	=	A	AND	Y	<	B)	
* http://use-the-index-luke.com/sql/partial-results/fetch-next-page#sb-equivalent-logic
☠
No proper index use*
Using OFFSET to fetch next rows
‣After adding FETCH	FIRST...ROWS	ONLY,
with SQL:2008, SQL:2011 introduced
OFFSET to skip rows.
‣Rows can be skipped with the ROWNUM
pseudo column too (ROWNUM	>	:x)
‣ROW_NUMBER() can do the trick too.
It doesn’t matter how to write it, ...
Using OFFSET to fetch next rows
OFFSET = SLEEP
The bigger the number,

the slower the execution.
Even worse: it eats up resources

and yields drifting results.
It’s All About Matching Queries to Indexes
Two steps to get the absolutely best access path:
1. Maximize data-locality
‣ Plain old B-tree index is the #1 tool for that
‣ Partitions are greatly overrated
‣ Table clusters are slightly underrated
2. Write the query to exploit it
‣ Use explicit range conditions
‣ Use top-n based termination
‣ Exploit index order
Thinking
in
Ordered

Sets
✓
✓
✓
✓
✓
✓
Index Smart,
Not Hard
About @MarkusWinand
‣Training for Developers
‣ SQL Performance (Indexing)
‣ Modern SQL
‣ On-Site or Online
‣SQL Tuning
‣ Index-Redesign
‣ Query Improvements
‣ On-Site or Online
http://winand.at/
About @MarkusWinand
@ModernSQL
http://modern-sql.com
@SQLPerfTips
http://use-the-index-luke.com

Contenu connexe

Tendances

SQL Server In-Memory OLTP Case Studies
SQL Server In-Memory OLTP Case StudiesSQL Server In-Memory OLTP Case Studies
SQL Server In-Memory OLTP Case Studiesjosdebruijn
 
On The Building Of A PostgreSQL Cluster
On The Building Of A PostgreSQL ClusterOn The Building Of A PostgreSQL Cluster
On The Building Of A PostgreSQL ClusterSrihari Sriraman
 
PostgreSQL Monitoring using modern software stacks
PostgreSQL Monitoring using modern software stacksPostgreSQL Monitoring using modern software stacks
PostgreSQL Monitoring using modern software stacksShowmax Engineering
 
What's new in MySQL 5.6
What's new in MySQL 5.6What's new in MySQL 5.6
What's new in MySQL 5.6Shlomi Noach
 
Understanding MySQL Performance through Benchmarking
Understanding MySQL Performance through BenchmarkingUnderstanding MySQL Performance through Benchmarking
Understanding MySQL Performance through BenchmarkingLaine Campbell
 
Postgres Vision 2018: Making Postgres Even Faster
Postgres Vision 2018: Making Postgres Even FasterPostgres Vision 2018: Making Postgres Even Faster
Postgres Vision 2018: Making Postgres Even FasterEDB
 
pgpool: Features and Development
pgpool: Features and Developmentpgpool: Features and Development
pgpool: Features and Developmentelliando dias
 
Managing and Visualizing your Replication Topologies with Orchestrator
Managing and Visualizing your Replication Topologies with OrchestratorManaging and Visualizing your Replication Topologies with Orchestrator
Managing and Visualizing your Replication Topologies with OrchestratorShlomi Noach
 
PostgreSQL Portland Performance Practice Project - Database Test 2 Howto
PostgreSQL Portland Performance Practice Project - Database Test 2 HowtoPostgreSQL Portland Performance Practice Project - Database Test 2 Howto
PostgreSQL Portland Performance Practice Project - Database Test 2 HowtoMark Wong
 
More on bpftrace for MariaDB DBAs and Developers - FOSDEM 2022 MariaDB Devroom
More on bpftrace for MariaDB DBAs and Developers - FOSDEM 2022 MariaDB DevroomMore on bpftrace for MariaDB DBAs and Developers - FOSDEM 2022 MariaDB Devroom
More on bpftrace for MariaDB DBAs and Developers - FOSDEM 2022 MariaDB DevroomValeriy Kravchuk
 
Postgresql database administration volume 1
Postgresql database administration volume 1Postgresql database administration volume 1
Postgresql database administration volume 1Federico Campoli
 
Built in physical and logical replication in postgresql-Firat Gulec
Built in physical and logical replication in postgresql-Firat GulecBuilt in physical and logical replication in postgresql-Firat Gulec
Built in physical and logical replication in postgresql-Firat GulecFIRAT GULEC
 
Tanel Poder Oracle Scripts and Tools (2010)
Tanel Poder Oracle Scripts and Tools (2010)Tanel Poder Oracle Scripts and Tools (2010)
Tanel Poder Oracle Scripts and Tools (2010)Tanel Poder
 
Как PostgreSQL работает с диском
Как PostgreSQL работает с дискомКак PostgreSQL работает с диском
Как PostgreSQL работает с дискомPostgreSQL-Consulting
 
In Memory Database In Action by Tanel Poder and Kerry Osborne
In Memory Database In Action by Tanel Poder and Kerry OsborneIn Memory Database In Action by Tanel Poder and Kerry Osborne
In Memory Database In Action by Tanel Poder and Kerry OsborneEnkitec
 
Troubleshooting PostgreSQL Streaming Replication
Troubleshooting PostgreSQL Streaming ReplicationTroubleshooting PostgreSQL Streaming Replication
Troubleshooting PostgreSQL Streaming ReplicationAlexey Lesovsky
 
Pseudo GTID and Easy MySQL Replication Topology Management
Pseudo GTID and Easy MySQL Replication Topology ManagementPseudo GTID and Easy MySQL Replication Topology Management
Pseudo GTID and Easy MySQL Replication Topology ManagementShlomi Noach
 
E bpf and dynamic tracing for mariadb db as (mariadb day during fosdem 2020)
E bpf and dynamic tracing for mariadb db as (mariadb day during fosdem 2020)E bpf and dynamic tracing for mariadb db as (mariadb day during fosdem 2020)
E bpf and dynamic tracing for mariadb db as (mariadb day during fosdem 2020)Valeriy Kravchuk
 

Tendances (20)

SQL Server In-Memory OLTP Case Studies
SQL Server In-Memory OLTP Case StudiesSQL Server In-Memory OLTP Case Studies
SQL Server In-Memory OLTP Case Studies
 
On The Building Of A PostgreSQL Cluster
On The Building Of A PostgreSQL ClusterOn The Building Of A PostgreSQL Cluster
On The Building Of A PostgreSQL Cluster
 
PostgreSQL Monitoring using modern software stacks
PostgreSQL Monitoring using modern software stacksPostgreSQL Monitoring using modern software stacks
PostgreSQL Monitoring using modern software stacks
 
What's new in MySQL 5.6
What's new in MySQL 5.6What's new in MySQL 5.6
What's new in MySQL 5.6
 
Understanding MySQL Performance through Benchmarking
Understanding MySQL Performance through BenchmarkingUnderstanding MySQL Performance through Benchmarking
Understanding MySQL Performance through Benchmarking
 
Postgres Vision 2018: Making Postgres Even Faster
Postgres Vision 2018: Making Postgres Even FasterPostgres Vision 2018: Making Postgres Even Faster
Postgres Vision 2018: Making Postgres Even Faster
 
pgpool: Features and Development
pgpool: Features and Developmentpgpool: Features and Development
pgpool: Features and Development
 
Managing and Visualizing your Replication Topologies with Orchestrator
Managing and Visualizing your Replication Topologies with OrchestratorManaging and Visualizing your Replication Topologies with Orchestrator
Managing and Visualizing your Replication Topologies with Orchestrator
 
PostgreSQL Portland Performance Practice Project - Database Test 2 Howto
PostgreSQL Portland Performance Practice Project - Database Test 2 HowtoPostgreSQL Portland Performance Practice Project - Database Test 2 Howto
PostgreSQL Portland Performance Practice Project - Database Test 2 Howto
 
More on bpftrace for MariaDB DBAs and Developers - FOSDEM 2022 MariaDB Devroom
More on bpftrace for MariaDB DBAs and Developers - FOSDEM 2022 MariaDB DevroomMore on bpftrace for MariaDB DBAs and Developers - FOSDEM 2022 MariaDB Devroom
More on bpftrace for MariaDB DBAs and Developers - FOSDEM 2022 MariaDB Devroom
 
Lock free programming- pro tips
Lock free programming- pro tipsLock free programming- pro tips
Lock free programming- pro tips
 
The Accidental DBA
The Accidental DBAThe Accidental DBA
The Accidental DBA
 
Postgresql database administration volume 1
Postgresql database administration volume 1Postgresql database administration volume 1
Postgresql database administration volume 1
 
Built in physical and logical replication in postgresql-Firat Gulec
Built in physical and logical replication in postgresql-Firat GulecBuilt in physical and logical replication in postgresql-Firat Gulec
Built in physical and logical replication in postgresql-Firat Gulec
 
Tanel Poder Oracle Scripts and Tools (2010)
Tanel Poder Oracle Scripts and Tools (2010)Tanel Poder Oracle Scripts and Tools (2010)
Tanel Poder Oracle Scripts and Tools (2010)
 
Как PostgreSQL работает с диском
Как PostgreSQL работает с дискомКак PostgreSQL работает с диском
Как PostgreSQL работает с диском
 
In Memory Database In Action by Tanel Poder and Kerry Osborne
In Memory Database In Action by Tanel Poder and Kerry OsborneIn Memory Database In Action by Tanel Poder and Kerry Osborne
In Memory Database In Action by Tanel Poder and Kerry Osborne
 
Troubleshooting PostgreSQL Streaming Replication
Troubleshooting PostgreSQL Streaming ReplicationTroubleshooting PostgreSQL Streaming Replication
Troubleshooting PostgreSQL Streaming Replication
 
Pseudo GTID and Easy MySQL Replication Topology Management
Pseudo GTID and Easy MySQL Replication Topology ManagementPseudo GTID and Easy MySQL Replication Topology Management
Pseudo GTID and Easy MySQL Replication Topology Management
 
E bpf and dynamic tracing for mariadb db as (mariadb day during fosdem 2020)
E bpf and dynamic tracing for mariadb db as (mariadb day during fosdem 2020)E bpf and dynamic tracing for mariadb db as (mariadb day during fosdem 2020)
E bpf and dynamic tracing for mariadb db as (mariadb day during fosdem 2020)
 

Similaire à Shaping Optimizer's Search Space

Scaling MySQL Strategies for Developers
Scaling MySQL Strategies for DevelopersScaling MySQL Strategies for Developers
Scaling MySQL Strategies for DevelopersJonathan Levin
 
Presentation interpreting execution plans for sql statements
Presentation    interpreting execution plans for sql statementsPresentation    interpreting execution plans for sql statements
Presentation interpreting execution plans for sql statementsxKinAnx
 
PostgreSQL query planner's internals
PostgreSQL query planner's internalsPostgreSQL query planner's internals
PostgreSQL query planner's internalsAlexey Ermakov
 
Top 10 Oracle SQL tuning tips
Top 10 Oracle SQL tuning tipsTop 10 Oracle SQL tuning tips
Top 10 Oracle SQL tuning tipsNirav Shah
 
My SQL Skills Killed the Server
My SQL Skills Killed the ServerMy SQL Skills Killed the Server
My SQL Skills Killed the ServerdevObjective
 
Myth busters - performance tuning 101 2007
Myth busters - performance tuning 101 2007Myth busters - performance tuning 101 2007
Myth busters - performance tuning 101 2007paulguerin
 
Sql query performance analysis
Sql query performance analysisSql query performance analysis
Sql query performance analysisRiteshkiit
 
MySQL Query Optimisation 101
MySQL Query Optimisation 101MySQL Query Optimisation 101
MySQL Query Optimisation 101Federico Razzoli
 
Sql query performance analysis
Sql query performance analysisSql query performance analysis
Sql query performance analysisRiteshkiit
 
MySQL Indexing : Improving Query Performance Using Index (Covering Index)
MySQL Indexing : Improving Query Performance Using Index (Covering Index)MySQL Indexing : Improving Query Performance Using Index (Covering Index)
MySQL Indexing : Improving Query Performance Using Index (Covering Index)Hemant Kumar Singh
 
How to use histograms to get better performance
How to use histograms to get better performanceHow to use histograms to get better performance
How to use histograms to get better performanceMariaDB plc
 
Using histograms to get better performance
Using histograms to get better performanceUsing histograms to get better performance
Using histograms to get better performanceSergey Petrunya
 
query-optimization-techniques_talk.pdf
query-optimization-techniques_talk.pdfquery-optimization-techniques_talk.pdf
query-optimization-techniques_talk.pdfgaros1
 
Query Optimizer in MariaDB 10.4
Query Optimizer in MariaDB 10.4Query Optimizer in MariaDB 10.4
Query Optimizer in MariaDB 10.4Sergey Petrunya
 
Explaining the explain_plan
Explaining the explain_planExplaining the explain_plan
Explaining the explain_planarief12H
 
Basic terminologies & asymptotic notations
Basic terminologies & asymptotic notationsBasic terminologies & asymptotic notations
Basic terminologies & asymptotic notationsRajendran
 

Similaire à Shaping Optimizer's Search Space (20)

Scaling MySQL Strategies for Developers
Scaling MySQL Strategies for DevelopersScaling MySQL Strategies for Developers
Scaling MySQL Strategies for Developers
 
MySQL performance tuning
MySQL performance tuningMySQL performance tuning
MySQL performance tuning
 
Presentation interpreting execution plans for sql statements
Presentation    interpreting execution plans for sql statementsPresentation    interpreting execution plans for sql statements
Presentation interpreting execution plans for sql statements
 
PostgreSQL query planner's internals
PostgreSQL query planner's internalsPostgreSQL query planner's internals
PostgreSQL query planner's internals
 
Top 10 Oracle SQL tuning tips
Top 10 Oracle SQL tuning tipsTop 10 Oracle SQL tuning tips
Top 10 Oracle SQL tuning tips
 
My SQL Skills Killed the Server
My SQL Skills Killed the ServerMy SQL Skills Killed the Server
My SQL Skills Killed the Server
 
Sql killedserver
Sql killedserverSql killedserver
Sql killedserver
 
Myth busters - performance tuning 101 2007
Myth busters - performance tuning 101 2007Myth busters - performance tuning 101 2007
Myth busters - performance tuning 101 2007
 
sqltuningcardinality1(1).ppt
sqltuningcardinality1(1).pptsqltuningcardinality1(1).ppt
sqltuningcardinality1(1).ppt
 
Sql query performance analysis
Sql query performance analysisSql query performance analysis
Sql query performance analysis
 
Quick Wins
Quick WinsQuick Wins
Quick Wins
 
MySQL Query Optimisation 101
MySQL Query Optimisation 101MySQL Query Optimisation 101
MySQL Query Optimisation 101
 
Sql query performance analysis
Sql query performance analysisSql query performance analysis
Sql query performance analysis
 
MySQL Indexing : Improving Query Performance Using Index (Covering Index)
MySQL Indexing : Improving Query Performance Using Index (Covering Index)MySQL Indexing : Improving Query Performance Using Index (Covering Index)
MySQL Indexing : Improving Query Performance Using Index (Covering Index)
 
How to use histograms to get better performance
How to use histograms to get better performanceHow to use histograms to get better performance
How to use histograms to get better performance
 
Using histograms to get better performance
Using histograms to get better performanceUsing histograms to get better performance
Using histograms to get better performance
 
query-optimization-techniques_talk.pdf
query-optimization-techniques_talk.pdfquery-optimization-techniques_talk.pdf
query-optimization-techniques_talk.pdf
 
Query Optimizer in MariaDB 10.4
Query Optimizer in MariaDB 10.4Query Optimizer in MariaDB 10.4
Query Optimizer in MariaDB 10.4
 
Explaining the explain_plan
Explaining the explain_planExplaining the explain_plan
Explaining the explain_plan
 
Basic terminologies & asymptotic notations
Basic terminologies & asymptotic notationsBasic terminologies & asymptotic notations
Basic terminologies & asymptotic notations
 

Plus de Gerger

Source Control for the Oracle Database
Source Control for the Oracle DatabaseSource Control for the Oracle Database
Source Control for the Oracle DatabaseGerger
 
Big Data for Oracle Professionals
Big Data for Oracle ProfessionalsBig Data for Oracle Professionals
Big Data for Oracle ProfessionalsGerger
 
Apache Spark, the Next Generation Cluster Computing
Apache Spark, the Next Generation Cluster ComputingApache Spark, the Next Generation Cluster Computing
Apache Spark, the Next Generation Cluster ComputingGerger
 
Best Way to Write SQL in Java
Best Way to Write SQL in JavaBest Way to Write SQL in Java
Best Way to Write SQL in JavaGerger
 
Version control for PL/SQL
Version control for PL/SQLVersion control for PL/SQL
Version control for PL/SQLGerger
 
Gitora, Version Control for PL/SQL
Gitora, Version Control for PL/SQLGitora, Version Control for PL/SQL
Gitora, Version Control for PL/SQLGerger
 
Gitora, Version Control for PL/SQL
Gitora, Version Control for PL/SQLGitora, Version Control for PL/SQL
Gitora, Version Control for PL/SQLGerger
 
Gitora, Version Control for PL/SQL
Gitora, Version Control for PL/SQLGitora, Version Control for PL/SQL
Gitora, Version Control for PL/SQLGerger
 
Monitoring Oracle Database Instances with Zabbix
Monitoring Oracle Database Instances with ZabbixMonitoring Oracle Database Instances with Zabbix
Monitoring Oracle Database Instances with ZabbixGerger
 
Introducing ProHuddle
Introducing ProHuddleIntroducing ProHuddle
Introducing ProHuddleGerger
 
Use Cases of Row Pattern Matching in Oracle 12c
Use Cases of Row Pattern Matching in Oracle 12cUse Cases of Row Pattern Matching in Oracle 12c
Use Cases of Row Pattern Matching in Oracle 12cGerger
 
Introducing Gitora,the version control tool for PL/SQL
Introducing Gitora,the version control tool for PL/SQLIntroducing Gitora,the version control tool for PL/SQL
Introducing Gitora,the version control tool for PL/SQLGerger
 

Plus de Gerger (12)

Source Control for the Oracle Database
Source Control for the Oracle DatabaseSource Control for the Oracle Database
Source Control for the Oracle Database
 
Big Data for Oracle Professionals
Big Data for Oracle ProfessionalsBig Data for Oracle Professionals
Big Data for Oracle Professionals
 
Apache Spark, the Next Generation Cluster Computing
Apache Spark, the Next Generation Cluster ComputingApache Spark, the Next Generation Cluster Computing
Apache Spark, the Next Generation Cluster Computing
 
Best Way to Write SQL in Java
Best Way to Write SQL in JavaBest Way to Write SQL in Java
Best Way to Write SQL in Java
 
Version control for PL/SQL
Version control for PL/SQLVersion control for PL/SQL
Version control for PL/SQL
 
Gitora, Version Control for PL/SQL
Gitora, Version Control for PL/SQLGitora, Version Control for PL/SQL
Gitora, Version Control for PL/SQL
 
Gitora, Version Control for PL/SQL
Gitora, Version Control for PL/SQLGitora, Version Control for PL/SQL
Gitora, Version Control for PL/SQL
 
Gitora, Version Control for PL/SQL
Gitora, Version Control for PL/SQLGitora, Version Control for PL/SQL
Gitora, Version Control for PL/SQL
 
Monitoring Oracle Database Instances with Zabbix
Monitoring Oracle Database Instances with ZabbixMonitoring Oracle Database Instances with Zabbix
Monitoring Oracle Database Instances with Zabbix
 
Introducing ProHuddle
Introducing ProHuddleIntroducing ProHuddle
Introducing ProHuddle
 
Use Cases of Row Pattern Matching in Oracle 12c
Use Cases of Row Pattern Matching in Oracle 12cUse Cases of Row Pattern Matching in Oracle 12c
Use Cases of Row Pattern Matching in Oracle 12c
 
Introducing Gitora,the version control tool for PL/SQL
Introducing Gitora,the version control tool for PL/SQLIntroducing Gitora,the version control tool for PL/SQL
Introducing Gitora,the version control tool for PL/SQL
 

Dernier

8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech studentsHimanshiGarg82
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnAmarnathKambale
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesVictorSzoltysek
 
tonesoftg
tonesoftgtonesoftg
tonesoftglanshi9
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplatePresentation.STUDIO
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsArshad QA
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Steffen Staab
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfonteinmasabamasaba
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrandmasabamasaba
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...Jittipong Loespradit
 
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Bert Jan Schrijver
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...SelfMade bd
 
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyviewmasabamasaba
 
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...masabamasaba
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...masabamasaba
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park %in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park masabamasaba
 

Dernier (20)

8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
 
tonesoftg
tonesoftgtonesoftg
tonesoftg
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
 
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
 
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
 
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
 
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park %in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
 

Shaping Optimizer's Search Space

  • 2. The Optimizer’s Search-Space is Limited “the query optimizer determines
 the most efficient execution plan*” ...most efficient? Out of what? *http://docs.oracle.com/cd/E16655_01/server.121/e15857/pfgrf_perf_overview.htm#TGDBA94082
  • 3. The Optimizer’s Search-Space is Limited The Optimizer... ‣Considers existing indexes only ➡ Other indexes might give even better performance ‣Doesn’t de-obfuscate queries very well ➡ Writing it in simpler terms might improve performance ‣Has built-in limitations ➡ Some theoretically possible plans are never considered
  • 4. Bring the Best Plan in the Search-Space ... it determines the most efficient execution plan out of the remaining ones. Before the optimizer can find the
 absolutely best plan we must first
 make sure it is within these boundaries.
  • 5.
  • 6.
  • 7. Two steps to get the absolutely best access path: 1. Maximize data-locality ‣ Plain old B-tree index is the #1 tool for that ‣ Partitions are greatly overrated ‣ Table clusters are slightly underrated It’s All About Matching Queries to Indexes 2. Write the query to exploit it ‣ Use explicit range conditions ‣ Use top-n based termination ‣ Exploit index order Thinking in Ordered
 Sets
  • 8. Visualizing Indexes as Pyramids Visualize Simplify
  • 9. The Order of Multi-Column Indexes
  • 10. The Order of Multi-Column Indexes
  • 11. The Order of Multi-Column Indexes
  • 12. Using Indexes: Column Order Defines Row-Locality Example: WHERE A > :a AND B = :b
  • 13. Using Indexes: Column Order Defines Row-Locality Example: WHERE A > :a AND B = :b
  • 14. Using Indexes: Column Order Defines Row-Locality Simple-man’s guidelines (best in ~97% of the cases): ‣ Conjunctive equality conditions are king Column order doesn’t affect data-locality ➡ Put them first into the index and choose the column order so that other queries can use the index too. ‣ Conjunctive range conditions are tricky Column order affects data-locality ➡ Put them after the equality columns. If there are multiple range conditions, put the most-selective first.
  • 15. Using Indexes: Column Order Defines Row-Locality Common mistakes: ‣ Arbitrary column order ☠ (bad) “Just put all columns from the where-clause in the index” ➡ Works only for all-conjunctive all-equality searches ➡ Doesn’t make the index useful for other queries ‣ Most-selective first ☠ (bad) “Order the columns according to the selectivity” ➡ Only valid to prioritize among multiple range conditions
  • 16. Using Indexes: Finding Bad Index Row-Locality ------------------------------------ | Id | Operation | ------------------------------------ | 0 | SELECT STATEMENT | | 1 | TABLE ACCESS BY INDEX ROWID| |* 2 | INDEX SKIP SCAN | ------------------------------------ Predicate Information: ------------------------------------ 2 - access("B"=20 AND "A">25) filter("B"=20) Index on (A, B) ------------------------------------ | Id | Operation | ------------------------------------ | 0 | SELECT STATEMENT | | 1 | TABLE ACCESS BY INDEX ROWID| |* 2 | INDEX RANGE SCAN | ------------------------------------ Predicate Information: ------------------------------------ 2 - access("B"=20 AND "A">25) Index on (B, A) Most
 efficient solution Most efficient
 workaround ‣ Index filter predicates are a “bad smell” ‣ Index Skip Scan is a “bad smell” ‣ Index Fast Full Scan is a “bad smell”
  • 17. Using Indexes: Trailing-Columns to Avoid Table-Access Example: SELECT C FROM X WHERE A > :a AND B = :b
  • 18. Using Indexes: Trailing-Columns to Avoid Table-Access Example: SELECT C FROM X WHERE A > :a AND B = :b
  • 19. Using Indexes: Trailing-Columns to Avoid Table-Access Add all needed columns to the index to avoid table access.
 The so-called index-only scan. ‣ Useful to nullify a bad clustering factor
 Consequently, not very useful if ➡ Clustering factor close to the number of table blocks or ➡ Selecting only a few rows ‣ A single non-indexed column breaks it No matter where it is mentioned (SELECT, ORDER BY,...) ➡ All or nothing: no benefit from adding some SELECT columns to the index.
  • 20. Using Indexes: Trailing-Columns to Avoid Table-Access Common mistakes: ‣ Selecting unneeded columns* ☠ (bad) SELECT * anybody? ORM-tools in use? Hooray! ➡ Adding many columns to many indexes is a no-no. ‣ Pushing too hard ☠ (bad) ➡ Index gets bigger, clustering factor (CF) gets worse ➡ Small benefit for low CF or if selecting a few rows only ➡ You’ll hit the hard limits (32 columns, 6398 bytes@8k) * http://use-the-index-luke.com/blog/2013-08/its-not-about-the-star-stupid
  • 21. It’s All About Matching Queries to Indexes Two steps to get the absolutely best access path: 1. Maximize data-locality ‣ Plain old B-tree index is the #1 tool for that ‣ Partitions are greatly overrated ‣ Table clusters are slightly underrated 2. Write the query to exploit it ‣ Use explicit range conditions ‣ Use top-n based termination ‣ Exploit index order Thinking in Ordered
 Sets ✓ ✓
  • 23. Example: List yesterday’s orders 1. Maximize data-locality
  • 24. Example: List yesterday’s orders 1. Lower bound:
 ORDER_DT >= TRUNC(sysdate-1) 2. Upper bound:
 ORDER_DT < TRUNC(sysdate) 2. Write query using explicit range conditions ---------------------------------------------- | Id | Operation | ---------------------------------------------- | 0 | SELECT STATEMENT | |* 1 | FILTER | | 2 | TABLE ACCESS BY INDEX ROWID BATCHED | |* 3 | INDEX RANGE SCAN | ---------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter(TRUNC(SYSDATE@!)>TRUNC(SYSDATE@!-1)) 3 - access("ORDER_DT">=TRUNC(SYSDATE@!-1) AND "ORDER_DT"<TRUNC(SYSDATE@!))
  • 25. Example: List yesterday’s orders Common anti-pattern: ‣TRUNC(order_dt)=:yesterday ☠ (bad) This is an “obfuscation” of the actual intention ➡ Requires function-based index
 CREATE INDEX … (TRUNC(order_dt)); ➡ Doesn’t support ordering by order_dt
 WHERE TRUNC(order_dt) = :yesterday
 ORDER BY order_dt DESC; Index
 not ordered by that
  • 28. Example: List yesterday’s orders reverse chronologically 2. Write query - exploit index order ---------------------------------------------- | Id | Operation | ---------------------------------------------- | 0 | SELECT STATEMENT | | 1 | SORT ORDER BY | | 2 | TABLE ACCESS BY INDEX ROWID BATCHED | |* 3 | INDEX RANGE SCAN | ---------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 3 - access("ORDERS"."SYS_NC00004$"=TRUNC(SYSDATE@!-1))    Tradeoff:
   CPU
  Memory
 IO
 1. Lower & upper bounds:
 TRUNC(ORDER_DT) 
 = TRUNC(sysdate)-1 2. Order
 ORDER BY ORDER_DT DESC

  • 29. Example: List orders from last 24 hours 1. Data-locality for the TRUNC variant * http://www.sqlfail.com/2014/05/05/oracle-can-now-use-function-based-indexes-in-queries-without-functions/
  • 30. 2. Write query using explicit range conditions Example: List orders from last 24 hours ------------------------------------------------- | Id | Operation | ------------------------------------------------- | 0 | SELECT STATEMENT | |* 1 | TABLE ACCESS BY INDEX ROWID BATCHED | |* 2 | INDEX RANGE SCAN on TRUNC(ORDER_DT) | ------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter("ORDER_DT">SYSDATE@!-1) 2 - access("ORDERS"."SYS_NC00004$">=TRUNC(SYSDATE@!-1)) 2. Upper bound: none (unbounded) 1. Lower bound:
 ORDER_DT > sysdate - 1 To use FBI Oracle adds (since 11.2.0.2*)
 TRUNC(ORDER_DT)>=TRUNC(sysdate-1) * http://www.sqlfail.com/2014/05/05/oracle-can-now-use-function-based-indexes-in-queries-without-functions/
  • 31. Example: List orders from last 24 hours 1. Maximize data-locality using straight index
  • 32. Example: List orders from last 24 hours 2. Write query using explicit range conditions 1. Lower bound:
 ORDER_DT > sysdate - 1 2. Upper bound: none (unbounded) -------------------------------------------- | Id | Operation | -------------------------------------------- | 0 | SELECT STATEMENT | | 1 | TABLE ACCESS BY INDEX ROWID BATCHED| |* 2 | INDEX RANGE SCAN | -------------------------------------------- Predicate Information: ---------------------- 2 - access("ORDER_DT">SYSDATE@!-1)
  • 33. Example: List orders from last 24 hours -------------------------------------------- | Id | Operation | -------------------------------------------- | 0 | SELECT STATEMENT | | 1 | TABLE ACCESS BY INDEX ROWID BATCHED| |* 2 | INDEX RANGE SCAN | -------------------------------------------- Predicate Information: ---------------------- 2 - access("ORDER_DT">SYSDATE@!-1) -------------------------------------------- | Id | Operation | -------------------------------------------- | 0 | SELECT STATEMENT | |* 1 | TABLE ACCESS BY INDEX ROWID BATCHED| |* 2 | INDEX RANGE SCAN | -------------------------------------------- Predicate Information: ---------------------- 1 - filter("ORDER_DT">SYSDATE@!-1) 2 - access("ORDERS"."SYS_NC00004$">=TRUNC(SYSDATE@!-1))   Most
  efficient solution   Most
  efficient
 workaround
  • 34. It’s All About Matching Queries to Indexes Two steps to get the absolutely best access path: 1. Maximize data-locality ‣ Plain old B-tree index is the #1 tool for that ‣ Partitions are greatly overrated ‣ Table clusters are slightly underrated 2. Write the query to exploit it ‣ Use explicit range conditions ‣ Use top-n based termination ‣ Exploit index order Thinking in Ordered
 Sets ✓ ✓ ✓ ✓
  • 35. Example: List 10 Most Recent Orders 1. Maximize data-locality
  • 36. Example: List 10 Most Recent Orders 2. Write query using explicit range conditions 1. Lower bound...? After 10 rows...??? 2. Upper bound? sysdate? Unbounded!
  • 37. Example: List 10 Most Recent Orders 1. Lower bound...? After 10 rows...??? 2. Upper bound? sysdate? Unbounded! 2. Write query using top-n based termination 3. Start with: most recent
 ORDER BY ORDER_DT DESC 4. Stop after: 10 rows
 FETCH FIRST 10 ROWS ONLY (since 12c)
  • 38. Example: List 10 Most Recent Orders 2. Write query using top-n based termination 3. Start with: most recent
 ORDER BY ORDER_DT DESC 4. Stop after: 10 rows
 FETCH FIRST 10 ROWS ONLY (since 12c) ---------------------------------------------------------- | Id | Operation | A-Rows | Buffers | ---------------------------------------------------------- | 0 | SELECT STATEMENT | 10 | 8 | |* 1 | VIEW | 10 | 8 | |* 2 | WINDOW NOSORT STOPKEY | 10 | 8 | | 3 | TABLE ACCESS BY INDEX ROWID| 11 | 8 | | 4 | INDEX FULL SCAN DESCENDING| 11 | 3 | ---------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter("from$_subquery$_002"."rowlimit_$$_rownumber"<=10) 2 - filter(ROW_NUMBER() OVER (ORDER BY ORDER_DT DESC)<=10) ROW_NUMBER() OVER (ORDER BY ORDER_DT DESC)<=10
  • 41. Window-Functions for Top-N Termination SELECT *
 FROM (
 SELECT orders.*
 , DENSE_RANK() OVER (
 ORDER BY TRUNC(order_dt) DESC
 ) rn
 FROM orders
 )
 WHERE rn <= 1
 ORDER BY order_dt DESC; Select 1 group
  • 42. Window-Functions for Top-N Termination SELECT *
 FROM (
 SELECT orders.*
 , DENSE_RANK() OVER (
 ORDER BY TRUNC(order_dt) DESC
 ) rn
 FROM orders
 )
 WHERE rn <= 1
 ORDER BY order_dt DESC; Useful to
 abort on edges
  • 43. Window-Functions for Top-N Termination SELECT *
 FROM (
 SELECT orders.*
 , DENSE_RANK() OVER (
 ORDER BY TRUNC(order_dt) DESC
 ) rn
 FROM orders
 )
 WHERE rn <= 1
 ORDER BY order_dt DESC; --------------------------------------------------------------------------- | Id | Operation | E-Rows | A-Rows | Buffers | Reads | --------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 2057 | 695 | 695 | | 1 | SORT ORDER BY | 100K| 2057 | 695 | 695 | |* 2 | VIEW | 100K| 2057 | 695 | 695 | |* 3 | WINDOW NOSORT STOPKEY | 100K| 2057 | 695 | 695 | | 4 | TABLE ACCESS BY INDEX ROWID| 100K| 2058 | 695 | 695 | | 5 | INDEX FULL SCAN DESCENDING| 100K| 2058 | 8 | 8 | --------------------------------------------------------------------------- DENSE_RANK
  • 44. Window-Functions for Top-N Termination SELECT *
 FROM orders
 WHERE TRUNC(order_dt)
 = (SELECT TRUNC(MAX(order_dt))
 FROM orders
 )
 ORDER BY order_dt ; --------------------------------------------------------------------------- | Id | Operation | E-Rows | A-Rows | Buffers | Reads | --------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 2057 | 695 | 695 | | 1 | SORT ORDER BY | 100K| 2057 | 695 | 695 | |* 2 | VIEW | 100K| 2057 | 695 | 695 | |* 3 | WINDOW NOSORT STOPKEY | 100K| 2057 | 695 | 695 | | 4 | TABLE ACCESS BY INDEX ROWID| 100K| 2058 | 695 | 695 | | 5 | INDEX FULL SCAN DESCENDING| 100K| 2058 | 8 | 8 | --------------------------------------------------------------------------- DENSE_RANK
  • 45. Window-Functions for Top-N Termination --------------------------------------------------------------------------------- | Id | Operation | E-Rows | A-Rows | Buffers | Reads | --------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 2057 | 1038 | 694 | | 1 | SORT ORDER BY | 3448 | 2057 | 1038 | 694 | | 2 | TABLE ACCESS BY INDEX ROWID BATCHED| 3448 | 2057 | 1038 | 694 | |* 3 | INDEX RANGE SCAN | 3448 | 2057 | 10 | 8 | | 4 | SORT AGGREGATE | 1 | 1 | 2 | 2 | | 5 | INDEX FULL SCAN (MIN/MAX) | 1 | 1 | 2 | 2 | --------------------------------------------------------------------------------- --------------------------------------------------------------------------- | Id | Operation | E-Rows | A-Rows | Buffers | Reads | --------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 2057 | 695 | 695 | | 1 | SORT ORDER BY | 100K| 2057 | 695 | 695 | |* 2 | VIEW | 100K| 2057 | 695 | 695 | |* 3 | WINDOW NOSORT STOPKEY | 100K| 2057 | 695 | 695 | | 4 | TABLE ACCESS BY INDEX ROWID| 100K| 2058 | 695 | 695 | | 5 | INDEX FULL SCAN DESCENDING| 100K| 2058 | 8 | 8 | --------------------------------------------------------------------------- DENSE_RANK SUB-SELECT
  • 46. Top-N vs. Max()-Subquery Common mistakes: ‣ Breaking ties with sub-queries ☠ (bad) WHERE (a, b)= (select max(a), max(b) ...) ➡ max() values coming from different rows... ➡ No rows selected. ‣ Selecting Nth largest ☠ (bad) WHERE X < (SELECT MAX()...
 WHERE X < (SELECT MAX()...)) WHERE (N-1) = (SELECT COUNT(DISTINCT(DT))...
  • 47. It’s All About Matching Queries to Indexes Two steps to get the absolutely best execution plan: 1. Maximize data-locality ‣ Plain old B-tree index is the #1 tool for that ‣ Partitions are greatly overrated ‣ Table clusters are slightly underrated 2. Write the query to exploit it ‣ Use explicit range conditions ‣ Use top-n based termination ‣ Exploit index order Thinking in Ordered
 Sets ✓ ✓ ✓ ✓ ✓
  • 49. Example: List next 10 orders 2. Use explicit range condition & top-n abort 1. Lower bound: unbounded (top-n) 2. Upper bound: where we stopped
 WHERE ORDER_DT < :prev_dt 3. ORDER BY ORDER_DT DESC 4. FETCH FIRST 10 ROWS ONLY What about ties?
  • 50. Explicit range conditions: the general case Example: List next 10 orders
  • 51. Explicit range conditions: the general case Example: List next 10 orders 1. Use definite sort order 2. Use Row-Value filter to remove what we have seen before (SQL:92) 3. Hit Enter
  • 52. Explicit range conditions: the general case Example: List next 10 orders
  • 53. Explicit range conditions: the general case Example: List next 10 orders (x,y) = (a,b) (x,y) IN ((a,b),(c,d)) (x,y) < (a,b) (x,y) > (a,b) ✓ ✓ ✗ ✗ Oracle limitation
  • 54. Explicit range conditions: the general case Example: List next 10 orders Oracle limitation Two semantically
 equivalent workarounds: X <= A AND NOT(X=A AND Y>=B) (X < A) OR (X = A AND Y < B) * http://use-the-index-luke.com/sql/partial-results/fetch-next-page#sb-equivalent-logic ☠ No proper index use*
  • 55. Using OFFSET to fetch next rows ‣After adding FETCH FIRST...ROWS ONLY, with SQL:2008, SQL:2011 introduced OFFSET to skip rows. ‣Rows can be skipped with the ROWNUM pseudo column too (ROWNUM > :x) ‣ROW_NUMBER() can do the trick too. It doesn’t matter how to write it, ...
  • 56. Using OFFSET to fetch next rows OFFSET = SLEEP The bigger the number,
 the slower the execution. Even worse: it eats up resources
 and yields drifting results.
  • 57. It’s All About Matching Queries to Indexes Two steps to get the absolutely best access path: 1. Maximize data-locality ‣ Plain old B-tree index is the #1 tool for that ‣ Partitions are greatly overrated ‣ Table clusters are slightly underrated 2. Write the query to exploit it ‣ Use explicit range conditions ‣ Use top-n based termination ‣ Exploit index order Thinking in Ordered
 Sets ✓ ✓ ✓ ✓ ✓ ✓
  • 58.
  • 60. About @MarkusWinand ‣Training for Developers ‣ SQL Performance (Indexing) ‣ Modern SQL ‣ On-Site or Online ‣SQL Tuning ‣ Index-Redesign ‣ Query Improvements ‣ On-Site or Online http://winand.at/