SlideShare a Scribd company logo
1 of 51
Download to read offline
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
MySQL 8.0:
Common Table Expressions
Guilhem Bichot – Lead Software Engineer
MySQL Optimizer Team, Oracle
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
Who
●
With MySQL AB / Sun / Oracle since 2002
●
Coder on the Server from 4.0 to 8.0
●
Replication, on-line backup, Maria storage
engine, optimizer...
●
Recent work:
– 5.7: for queries with GROUP BY, sql_mode=only_full_group_by
smarter and enabled by default (see blog links at end)
– 8.0: [recursive] common table expressions
●
Guilhem.bichot@<theBigO>
2
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
Program Agenda
Non-recursive common table expressions
Recursive common table expressions
1
2
3
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
Program Agenda
Non-recursive common table expressions
Recursive common table expressions
1
2
4
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
What is a Common Table Expression?
• In official MySQL 8.0.1+.
• A derived table is a subquery in the FROM clause
SELECT … FROM (subquery) AS derived, t1 …
• A Common Table Expression (CTE) is just like a derived table,
but its declaration is moved to before the query
WITH cte AS (subquery) SELECT … FROM cte, t1 …
• SQL:99: a named (sub)query, “Query Name”. MSSQL, PG: A
“Table Expression” (~subquery) which is put in “Common”.
ORCL: a factored out subquery, “Subquery Factoring”.
5
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
How do I create a CTE?
WITH cte_name [( <list of column names> )] AS
(
SELECT ... # Definition
)
[, <any number of other CTE definitions> ]
<SELECT/UPDATE/DELETE statement, referencing the CTEs>
6
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
Giving names to columns of the CTE
●
Default naming: from selected expressions
WITH cte AS (SELECT a+2, b FROM t1)
SELECT cte.`a+2` + 10 FROM cte;
●
Custom naming, alt. 1: give alias to the selected expressions
WITH cte AS (SELECT a+2 AS a, b FROM t1)
SELECT cte.a + 10 FROM cte;
●
Custom naming, alt. 2: list names right after CTE's name
WITH cte(a, b) AS (SELECT a+2, b FROM t2)
SELECT cte.a + 10 FROM cte;
– Side-note: also added same feature to derived table:
SELECT … FROM (SELECT a+2,b …) AS derived(a,b);
(views already had that: CREATE VIEW v(a,b) AS SELECT ...)
7
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
Two strategies of evaluation for a CTE
WITH cte AS (SELECT a FROM t1 WHERE a<5)
SELECT * FROM cte, t2 WHERE cte.a>3;
●
“cte” may be materialized:
– Evaluate SELECT a FROM t1 WHERE a<5
– Store that in transient temporary table named “cte” with column named
“a”
– Do: SELECT * FROM cte, t2 WHERE cte.a>3;
– Optimizer may create indexes on the temporary table to speed up
predicates like cte.a=t2.b (look for “auto_key” in “key” column in EXPLAIN).
●
Or “cte” may be merged:
– SELECT * FROM t1, t2 WHERE t1.a>3 AND t1.a<5;
– good if outer predicate cte.a>3 is selective while inner a<5 is not.
8
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
Two strategies of evaluation for a CTE
WITH cte AS (SELECT a FROM t1 WHERE a<5)
SELECT * FROM cte, t2 WHERE cte.a>3;
●
Choice between the two strategies, materialization vs merging:
– Heuristics
– Technical constraints prevent merging
●
e.g. if CTE contains GROUP BY or is recursive: always materialized
– Hint:
●
/*+ MERGE(cte) */
●
/*+ NO_MERGE(cte) */
●
Set @@optimizer_switch=”derived_merge=on|off”
●
Applicable to CTEs, views and derived tables
9
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
CTE can be local to subquery
WITH cte AS (SELECT a+2 AS a, b FROM t2)
SELECT * FROM t1 WHERE t1.a IN
(SELECT a * 3 FROM cte); # Scope: “cte” is visible to top SELECT
vs
SELECT * FROM t1 WHERE t1.a IN
(WITH cte AS (SELECT a+2 AS a, b FROM t2)
SELECT a * 3 FROM cte); # Scope: “cte” is not visible to top SELECT
10
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
CTEs allowed in other statements
Can use CTE as read-only source to update other tables:
WITH cte AS (SELECT a+2 AS a, b FROM t2)
UPDATE t1, cte SET t1.a=cte.b + 10 WHERE t1.a = cte.a;
WITH cte AS (SELECT a+2 AS a, b FROM t2)
DELETE t1 FROM t1, cte WHERE t1.a = cte.a;
INSERT INTO t2
WITH cte AS (SELECT a+2 AS a, b FROM t2)
SELECT * FROM cte;
11
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
Common Table Expression vs. Derived Table
Better readability
Can be referenced multiple times
Easier chaining
Improved performance
12
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
Better readability
• Derived table:
SELECT dt.a
FROM t1 LEFT JOIN
((SELECT … FROM …) AS dt JOIN t2 ON …) ON …
– If reading top to bottom...
– … You first see dt.a … so what's dt ?
– … Read on, it's deeply nested somewhere...
• CTE:
WITH dt AS (SELECT ... FROM ...)
SELECT dt.a
FROM t1 LEFT JOIN (dt JOIN t2 ON ...) ON …
13
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
Easier chaining
• Derived table cannot refer to a neighbour derived
table:
SELECT …
FROM (SELECT … FROM …) AS d1,
(SELECT … FROM d1 …) AS d2 …
ERROR: 1146 (42S02): Table ‘db.d1’ doesn’t exist
• Workaround: nest d1 in d2
SELECT …
FROM (SELECT … FROM (SELECT … FROM …) AS d1 …) AS d2
• Works but leads to nesting, is not very readable
14
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
Easier chaining
• CTE can refer to a neighbour CTE:
WITH d1 AS (SELECT … FROM …),
d2 AS (SELECT … FROM d1 …)
SELECT
FROM d1, d2 …
●
More readable this way
15
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
Example of chaining
WITH sales_by_month(month,total) AS
# first CTE: one row per month, with amount sold on all days of month
(SELECT MONTH(day_of_sale), SUM(amount) FROM sales_days
WHERE YEAR(day_of_sale)=2017
GROUP BY MONTH(day_of_sale)),
best_month(month, total, award) AS # second CTE: best month
(SELECT month, total, "best" FROM sales_by_month
WHERE total=(SELECT MAX(total) FROM sales_by_month)),
worst_month(month, total, award) AS # 3rd CTE: worst month
(SELECT month, total, "worst" FROM sales_by_month
WHERE total=(SELECT MIN(total) FROM sales_by_month))
# Now show best, worst and difference:
SELECT * FROM best_month UNION ALL SELECT * FROM worst_month
UNION ALL SELECT NULL, bm.total - wm.total, “diff”
FROM best_month bm, worst_month wm;
16
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
Example of chaining
Result:
+-------+-------+-------+
| month | total | award |
+-------+-------+-------+
| 1 | 300 | best |
| 3 | 11 | worst |
| NULL | 289 | diff |
+-------+-------+-------+
17
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
Can be referenced multiple times
• If you want to make N references to a derived table you
must write N definitions: in the previous query you would
need to write (copy) eight times the definition of
sales_by_month
• CTE can be referenced multiple times: sales_by_month is
referenced four times, best_month two times...
18
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
Better Performance: DBT3 (TPC-H) Query 15
CREATE VIEW revenue0 (r_supplier_no, r_total_revenue)
AS SELECT l_suppkey, SUM(l_extendedprice * (1-l_discount))
FROM  lineitem
WHERE l_shipdate >= '1996-07-01' 
AND l_shipdate < DATE_ADD('1996-07-01‘, INTERVAL '90' day)
GROUP BY  l_suppkey;
SELECT s_suppkey, s_name, s_address, s_phone, r_total_revenue
FROM supplier, revenue0
WHERE s_suppkey = r_supplier_no
AND r_total_revenue =
(SELECT MAX(r_total_revenue) FROM revenue0)
ORDER BY s_suppkey;
“Top Supplier Query”
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
Materialization of view
DBT-3 Query 15
ORDER JOIN
Supplier
(eq_ref)
GROUP Lineitem
(range)
Materialize
GROUP Lineitem
(range)
Materialize
SELECT
S
u
b
q
u
e
r
y
Revenue0
Revenue0
W
H
ERE
FROM
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
DBT-3 Query 15
EXPLAIN
CTE
id select type table type possible keys key rows
1 PRIMARY <derived3> ALL NULL NULL 4801074
1 PRIMARY supplier eq_ref PRIMARY PRIMARY 1
3 DERIVED lineitem range i_l_shipdate, ... i_l_shipdate 4801074
2 SUBQUERY <derived4> ALL NULL NULL 4801074
4 DERIVED lineitem range i_l_shipdate, ... i_l_shipdate 4801074
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
Rewritten to use a CTE
WITH revenue0 (r_supplier_no, r_total_revenue) AS
(SELECT l_suppkey, SUM(l_extendedprice * (1-l_discount))
FROM  lineitem
WHERE l_shipdate >= '1996-07-01' 
AND l_shipdate < DATE_ADD('1996-07-01‘, INTERVAL '90' day)
GROUP BY  l_suppkey) /* same definition as view's */
SELECT s_suppkey, s_name, s_address, s_phone, r_total_revenue
FROM supplier, revenue0
WHERE s_suppkey = r_supplier_no
AND r_total_revenue =
(SELECT MAX(r_total_revenue) FROM revenue0)
ORDER BY s_suppkey;
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
DBT-3 Query 15, CTE
EXPLAIN
CTE
id select type table type possible keys key rows
1 PRIMARY <derived2> ALL NULL NULL 4801074
1 PRIMARY supplier eq_ref PRIMARY PRIMARY 1
3 SUBQUERY <derived2> ALL NULL NULL 4801074
2 DERIVED lineitem range i_l_shipdate, ... i_l_shipdate 4801074
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
DBT-3 Query 15
Materialization of CTE
ORDER JOIN
Supplier
(eq_ref)
GROUP Lineitem
(range)
Materialize
SELECT
S
u
b
q
u
e
r
y
Revenue0
W
H
ERE
FROM
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
DBT-3 Query 15
25
Query Performance
View CTE
0
2
4
6
8
10
12
14
16
18
Query Execution Time (seconds)
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
Single-materialized CTE
• N references but one temporary table
• Reduces disk usage, memory usage, execution time
• Possibly a different auto_key index for each reference
– WITH cte AS (…) SELECT … FROM cte AS cte1, cte AS
cte2 WHERE cte1.a=3 AND cte2.b=5
– Automatically adds index on cte.a and index on cte.b
– In EXPLAIN: <auto_key0>, <auto_key1>, …
• Can be better than CTE merging, if outer predicates are not
very selective or base tables in CTE's subquery are poorly
indexed
26
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
Single-materialized CTE
• Handy if CTE contains some random value to be used twice
• Lottery: find all rows of t1 where column “age” is +-5 around
a certain random threshold, and also display the chosen
threshold.
• WITH cte(rnd) AS (SELECT ROUND(RAND()*125)
SELECT t1.name, cte.rnd FROM cte, t1
WHERE t1.age BETWEEN cte.rnd-5 AND cte.rnd+5
• Single materialization gives same value to all three uses of
cte.rnd.
27
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
Program Agenda
Non-recursive common table expressions
Recursive common table expressions
1
2
28
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
Recursive CTE
• A recursive CTE refers to itself in the defining subquery
• Always materialized into transient temporary table
• Seed SELECT is executed once to create the first data subset
• Recursive SELECT is repeatedly executed to return new
subsets of data: to the eyes of iteration N+1, “cte” = subset
produced by iteration N, and only that.
29
WITH RECURSIVE cte AS
( SELECT ... FROM table_name /* "seed" SELECT */
UNION [DISTINCT|ALL]
SELECT ... FROM cte, table_name /* recursive SELECT */
WHERE …)
SELECT ... FROM cte; /* outer query */
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
Recursive CTE
• The process stops when an iteration does not generate any
row
• The union of all subsets is stored into a transient temporary
table; to the eyes of the outer query, “cte” = that table.
• Useful to
– Generate series (start:end:step)
– Explore hierarchies (parent/child, part/subpart, trees),
connections (graphs)
30
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
Recursive CTE
31
A simple example : start:end:step sequence of values
Print 1 to 10 :
WITH RECURSIVE cte AS
( SELECT 1 AS a
UNION ALL
SELECT 1+a FROM cte
WHERE a<10
)
SELECT * FROM cte;
a
1 # Seed SELECT
2 # Recursive SELECT, it. 1
3 # Recursive SELECT, it. 2
4
5
6
7
8
9
10
∅... because 10<10 is false
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
Recursive CTE
32
Note the fixpoint
The final 'cte' satisfies :
cte ==
( SELECT 1 AS a
UNION ALL
SELECT 1+a FROM cte
WHERE a<10 )
a
1
2
3
4
5
6
7
8
9
10
a
1
a
1
2
3
4
5
6
7
8
9
10
a
2
3
4
5
6
7
8
9
10
a
1
2
3
4
5
6
7
8
9
10
cte
WHERE
a<10 a+1
UNION
ALL
=cte!
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
Recursive CTE
• Find the fixpoint(s) i.e. the solution(s) to X = F(X), X is a set
• Assuming F is monotonic - if Y contains X, F(Y) contains F(X)
• F(∅), F(F(∅)), F(F(F(∅))), … will stagnate at some point
• So the fixpoint exists and we found it
• Requirement 1: F must be monotonic
• But iterating F over growing sets is costly
• Optimization: iterate F over new rows only
– Works only if F doesn't join X with itself (linear recursion)
33
Fixpoint (~10 years of research & discussion in SQL committee)
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
Recursive CTE
• A recursive SELECT must reference the CTE
– in its FROM clause, and only once (or miss “new JOIN old” ⇒linear)
– not in any subquery (NOT EXISTS (subquery) ⇒monotonic)
– not as the right table of a left join (row disappears ⇒monotonic)
●
A recursive SELECT must not contain
– GROUP BY or aggregate/window functions (SUM, LEAD)
(aggregated SUM changes ⇒monotonic)
– ORDER BY, LIMIT or DISTINCT (MySQL-specific restriction)
●
My one-line rule: an iteration handles one row in isolation.
34
SQL-standard restrictions
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
Recursive CTE
35
Implementation: greedy reading over an open-ended tmp table
1
Seed done Recursive SELECT………………………………………………………………………………...
1 1
2
1
2
1
2
3
Read pointer
Write pointer
1
2
3
4
5
6
7
8
9
10
1
2
3
4
5
6
7
8
9
10
And
So
on
Theory : run the recursive SELECT ten times ; implementation: run it once.
FIFOqueue
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
Recursive CTE
• Numbers 1-10 is a one-level recursive sequence
– value N+1 = function of value N
• Two-level recursive sequence is possible
– value N+2 = function of value N and value N+1
– like Fibonacci numbers
– However “an iteration handles one row in isolation”
– So let the row for N+1 also contain a “recall” of N, in an
extra column.
• With INSERT SELECT, the sequence can be stored in a table
36
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
Date sequence
37
Missing dates
SELECT orderdate,
SUM(totalprice) sales
FROM orders
GROUP BY orderdate
ORDER BY orderdate;
+------------+-----------+
| orderdate | sales |
+------------+-----------+
| 2016-09-01 | 43129.83 |
| 2016-09-03 | 218347.61 |
| 2016-09-04 | 142568.40 |
| 2016-09-05 | 299244.83 |
| 2016-09-07 | 185991.79 |
+------------+-----------+
Missing September 2nd and 6th...
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
Date sequence
38
All dates
WITH RECURSIVE dates(date) AS
( SELECT '2016-09-01'
UNION ALL
SELECT DATE_ADD(date,
INTERVAL 1 DAY)
FROM dates
WHERE date < '2016-09-07‘ )
SELECT dates.date,
COALESCE(SUM(totalprice), 0) sales
FROM dates LEFT JOIN orders
ON dates.date = orders.orderdate
GROUP BY dates.date
ORDER BY dates.date;
+------------+-----------+
| date | sales |
+------------+-----------+
| 2016-09-01 | 43129.83 |
| 2016-09-02 | 0.00 |
| 2016-09-03 | 218347.61 |
| 2016-09-04 | 142568.40 |
| 2016-09-05 | 299244.83 |
| 2016-09-06 | 0.00 |
| 2016-09-07 | 185991.79 |
+------------+-----------+
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
Hierarchy Traversal
39
Employee database
CREATE TABLE employees (
id INT PRIMARY KEY,
name VARCHAR(100),
manager_id INT,
FOREIGN KEY (manager_id)
REFERENCES employees(id) );
INSERT INTO employees VALUES
(333, "Yasmina", NULL), # CEO
(198, "John", 333), # J reports to Y
(692, "Tarek", 333),
(29, "Pedro", 198),
(4610, "Sarah", 29),
(72, "Pierre", 29),
(123, "Adil", 692);
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
Hierarchy Traversal
40
Employee database
Yasmina (333)
John (198) Tarek (692)
Pedro (29)
Sarah (4610) Pierre (72)
Adil (123)
(BF)(DF)(NO)
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
Hierarchy Traversal
41
How to walk the tree
Yasmina (333)
John (198) Tarek (692)
Pedro (29)
Sarah (4610) Pierre (72)
Adil (123)
Seed
Iteration 1
Iteration 2
Iteration 3
Iteration 4
∅
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
Hierarchy Traversal
42
Find reporting chain for every employee
WITH RECURSIVE
emp_ext (id, name, path) AS (
SELECT id, name, CAST(id AS CHAR(200))
FROM employees
WHERE manager_id IS NULL
UNION ALL
SELECT s.id, s.name,
CONCAT(m.path, ",", s.id)
FROM emp_ext m JOIN employees s
ON m.id=s.manager_id )
SELECT * FROM emp_ext ;
id name path
333 Yasmina 333
198 John 333,198
692 Tarek 333,692
29 Pedro 333,198,29
123 Adil 333,692,123
4610 Sarah 333,198,29,4610
72 Pierre 333,198,29,72
∅
Note : no guaranteed output order
(tree)
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
Hierarchy Traversal
43
Reporting chain, depth first: “children” before “brothers”
WITH RECURSIVE
emp_ext (id, name, path) AS (
SELECT id, name, CAST(id AS CHAR(200))
FROM employees
WHERE manager_id IS NULL
UNION ALL
SELECT s.id, s.name,
CONCAT(m.path, ",", s.id)
FROM emp_ext m JOIN employees s
ON m.id=s.manager_id )
SELECT * FROM emp_ext ORDER BY path;
id name path
333 Yasmina 333
198 John 333,198
29 Pedro 333,198,29
4610 Sarah 333,198,29,4610
72 Pierre 333,198,29,72
692 Tarek 333,692
123 Adil 333,692,123
(tree)
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
Hierarchy Traversal
44
Reporting chain, breadth first: “brothers” before “children”
WITH RECURSIVE
emp_ext (id, name, path, lvl) AS (
SELECT id, name,
CAST(id AS CHAR(200)), 1
FROM employees
WHERE manager_id IS NULL
UNION ALL
SELECT s.id, s.name,
CONCAT(m.path, ",", s.id), m.lvl + 1
FROM emp_ext m JOIN employees s
ON m.id=s.manager_id )
SELECT * FROM emp_ext ORDER BY lvl;
id name path lvl
333 Yasmina 333 1
198 John 333,198 2
692 Tarek 333,692 2
29 Pedro 333,198,29 3
123 Adil 333,692,123 3
4610 Sarah 333,198,29,4610 4
72 Pierre 333,198,29,72 4
(tree)
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
Recursive CTE – complete syntax
WITH RECURSIVE cte_name [ list of column names ] AS
(
SELECT ... <-- specifies initial set
UNION [DISTINCT|ALL]
SELECT ... <-- specifies initial set
UNION [DISTINCT|ALL]
...
SELECT ... <-- specifies how to derive new rows
UNION [DISTINCT|ALL]
SELECT ... <-- specifies how to derive new rows
...
)
[, any number of other CTE definitions ]
<SELECT/UPDATE/DELETE statement, referencing the CTEs>
45
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
Recursive CTE – goodies!
●
UNION DISTINCT to add only non-duplicate rows
– Think: walking a graph to find “all direct and indirect connections of A” (a.k.a.
build the transitive closure of A): A->B->C->A
– Several well-known commercial DBMSs don't support UNION DISTINCT
●
Flagging abnormal cycles:
– Leverage the PATH column
– A new row is closing a cycle if it's already in the PATH (test with FIND_IN_SET)
●
More tips about cycles: see my blogs (last slides)
46
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
Recursive CTE – goodies!
●
Runaway query:
– Forgot the WHERE in recursive SELECT, or typed it wrong (a<0 in lieu of a>0)
– Or: unexpected cycle in my data
●
You're covered:
WITH RECURSIVE cte AS
( SELECT 1 AS a UNION ALL SELECT 1+a FROM cte )
SELECT * FROM cte;
ERROR HY000: Recursive query aborted after 1001 iterations. Try
increasing @@cte_max_recursion_depth to a larger value.
47
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
Want to try it out?
• Available since version 8.0.1
• Install MySQL Server 8.0.3 (Release Candidate)
– Bonus over 8.0.1:
●
@@cte_max_recursion_depth variable
●
A couple of bugfixes
●
No known bugs
48
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
Want to learn more?
• My four blog posts:
http://mysqlserverteam.com/mysql-8-0-labs-recursive-common-table-ex
pressions-in-mysql-ctes
• https://dev.mysql.com/doc/refman/8.0/en/with.html
• MySQL Optimizer & Parser forum:
http://forums.mysql.com/list.php?115
• Shameless plug ☺ only_full_group_by improvements in 5.7:
http://mysqlserverteam.com/mysql-5-7-only_full_group_by-
improved-recognizing-functional-dependencies-enabled-by-
default/
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
Safe Harbor Statement
The preceding is intended to outline our general product direction. It is
intended for information purposes only, and may not be incorporated
into any contract. It is not a commitment to deliver any material, code,
or functionality, and should not be relied upon in making purchasing
decisions. The development, release, and timing of any features or
functionality described for Oracle’s products remains at the sole
discretion of Oracle.
50
Ctes percona live_2017

More Related Content

What's hot

LATERAL Derived Tables in MySQL 8.0
LATERAL Derived Tables in MySQL 8.0LATERAL Derived Tables in MySQL 8.0
LATERAL Derived Tables in MySQL 8.0Norvald Ryeng
 
The Five Best Things To Happen To SQL
The Five Best Things To Happen To SQLThe Five Best Things To Happen To SQL
The Five Best Things To Happen To SQLConnor McDonald
 
Using Optimizer Hints to Improve MySQL Query Performance
Using Optimizer Hints to Improve MySQL Query PerformanceUsing Optimizer Hints to Improve MySQL Query Performance
Using Optimizer Hints to Improve MySQL Query Performanceoysteing
 
Oracle tips and tricks
Oracle tips and tricksOracle tips and tricks
Oracle tips and tricksYanli Liu
 
Oracle 9i notes(kamal.love@gmail.com)
Oracle 9i  notes(kamal.love@gmail.com)Oracle 9i  notes(kamal.love@gmail.com)
Oracle 9i notes(kamal.love@gmail.com)Kamal Raj
 
How to analyze and tune sql queries for better performance percona15
How to analyze and tune sql queries for better performance percona15How to analyze and tune sql queries for better performance percona15
How to analyze and tune sql queries for better performance percona15oysteing
 
Powerful Explain in MySQL 5.6
Powerful Explain in MySQL 5.6Powerful Explain in MySQL 5.6
Powerful Explain in MySQL 5.6MYXPLAIN
 
How to analyze and tune sql queries for better performance webinar
How to analyze and tune sql queries for better performance webinarHow to analyze and tune sql queries for better performance webinar
How to analyze and tune sql queries for better performance webinaroysteing
 
Polymorphic Table Functions in 18c
Polymorphic Table Functions in 18cPolymorphic Table Functions in 18c
Polymorphic Table Functions in 18cAndrej Pashchenko
 
New SQL features in latest MySQL releases
New SQL features in latest MySQL releasesNew SQL features in latest MySQL releases
New SQL features in latest MySQL releasesGeorgi Sotirov
 
Advanced tips of dbms statas
Advanced tips of dbms statasAdvanced tips of dbms statas
Advanced tips of dbms statasLouis liu
 
SQL Macros - Game Changing Feature for SQL Developers?
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 Pashchenko
 
SQL Pattern Matching – should I start using it?
SQL Pattern Matching – should I start using it?SQL Pattern Matching – should I start using it?
SQL Pattern Matching – should I start using it?Andrej Pashchenko
 
Database Oracle Basic
Database Oracle BasicDatabase Oracle Basic
Database Oracle BasicKamlesh Singh
 

What's hot (20)

LATERAL Derived Tables in MySQL 8.0
LATERAL Derived Tables in MySQL 8.0LATERAL Derived Tables in MySQL 8.0
LATERAL Derived Tables in MySQL 8.0
 
The Five Best Things To Happen To SQL
The Five Best Things To Happen To SQLThe Five Best Things To Happen To SQL
The Five Best Things To Happen To SQL
 
Using Optimizer Hints to Improve MySQL Query Performance
Using Optimizer Hints to Improve MySQL Query PerformanceUsing Optimizer Hints to Improve MySQL Query Performance
Using Optimizer Hints to Improve MySQL Query Performance
 
Oracle tips and tricks
Oracle tips and tricksOracle tips and tricks
Oracle tips and tricks
 
Oracle 9i notes(kamal.love@gmail.com)
Oracle 9i  notes(kamal.love@gmail.com)Oracle 9i  notes(kamal.love@gmail.com)
Oracle 9i notes(kamal.love@gmail.com)
 
Sequences and indexes
Sequences and indexesSequences and indexes
Sequences and indexes
 
How to analyze and tune sql queries for better performance percona15
How to analyze and tune sql queries for better performance percona15How to analyze and tune sql queries for better performance percona15
How to analyze and tune sql queries for better performance percona15
 
Powerful Explain in MySQL 5.6
Powerful Explain in MySQL 5.6Powerful Explain in MySQL 5.6
Powerful Explain in MySQL 5.6
 
How to analyze and tune sql queries for better performance webinar
How to analyze and tune sql queries for better performance webinarHow to analyze and tune sql queries for better performance webinar
How to analyze and tune sql queries for better performance webinar
 
Polymorphic Table Functions in 18c
Polymorphic Table Functions in 18cPolymorphic Table Functions in 18c
Polymorphic Table Functions in 18c
 
New SQL features in latest MySQL releases
New SQL features in latest MySQL releasesNew SQL features in latest MySQL releases
New SQL features in latest MySQL releases
 
Api presentation
Api presentationApi presentation
Api presentation
 
plsql Les08
plsql Les08 plsql Les08
plsql Les08
 
Advanced tips of dbms statas
Advanced tips of dbms statasAdvanced tips of dbms statas
Advanced tips of dbms statas
 
Do You Know The 11g Plan?
Do You Know The 11g Plan?Do You Know The 11g Plan?
Do You Know The 11g Plan?
 
plsql Les09
 plsql Les09 plsql Les09
plsql Les09
 
SQL Macros - Game Changing Feature for SQL Developers?
SQL Macros - Game Changing Feature for SQL Developers?SQL Macros - Game Changing Feature for SQL Developers?
SQL Macros - Game Changing Feature for SQL Developers?
 
Les09 Manipulating Data
Les09 Manipulating DataLes09 Manipulating Data
Les09 Manipulating Data
 
SQL Pattern Matching – should I start using it?
SQL Pattern Matching – should I start using it?SQL Pattern Matching – should I start using it?
SQL Pattern Matching – should I start using it?
 
Database Oracle Basic
Database Oracle BasicDatabase Oracle Basic
Database Oracle Basic
 

Similar to Ctes percona live_2017

Common Table Expressions (CTE) & Window Functions in MySQL 8.0
Common Table Expressions (CTE) & Window Functions in MySQL 8.0Common Table Expressions (CTE) & Window Functions in MySQL 8.0
Common Table Expressions (CTE) & Window Functions in MySQL 8.0oysteing
 
MySQL Optimizer: What's New in 8.0
MySQL Optimizer: What's New in 8.0MySQL Optimizer: What's New in 8.0
MySQL Optimizer: What's New in 8.0Manyi Lu
 
MySQL Optimizer Overview
MySQL Optimizer OverviewMySQL Optimizer Overview
MySQL Optimizer OverviewOlav Sandstå
 
MySQL Optimizer Overview
MySQL Optimizer OverviewMySQL Optimizer Overview
MySQL Optimizer OverviewOlav Sandstå
 
ClickHouse Query Performance Tips and Tricks, by Robert Hodges, Altinity CEO
ClickHouse Query Performance Tips and Tricks, by Robert Hodges, Altinity CEOClickHouse Query Performance Tips and Tricks, by Robert Hodges, Altinity CEO
ClickHouse Query Performance Tips and Tricks, by Robert Hodges, Altinity CEOAltinity Ltd
 
Webinar slides: MORE secrets of ClickHouse Query Performance. By Robert Hodge...
Webinar slides: MORE secrets of ClickHouse Query Performance. By Robert Hodge...Webinar slides: MORE secrets of ClickHouse Query Performance. By Robert Hodge...
Webinar slides: MORE secrets of ClickHouse Query Performance. By Robert Hodge...Altinity Ltd
 
Beginers guide for oracle sql
Beginers guide for oracle sqlBeginers guide for oracle sql
Beginers guide for oracle sqlN.Jagadish Kumar
 
Wellington APAC Groundbreakers tour - Upgrading to the 12c Optimizer
Wellington APAC Groundbreakers tour - Upgrading to the 12c OptimizerWellington APAC Groundbreakers tour - Upgrading to the 12c Optimizer
Wellington APAC Groundbreakers tour - Upgrading to the 12c OptimizerConnor McDonald
 
Explain the explain_plan
Explain the explain_planExplain the explain_plan
Explain the explain_planMaria Colgan
 
MySQL 8.0: What Is New in Optimizer and Executor?
MySQL 8.0: What Is New in Optimizer and Executor?MySQL 8.0: What Is New in Optimizer and Executor?
MySQL 8.0: What Is New in Optimizer and Executor?Norvald Ryeng
 
Wellington APAC Groundbreakers tour - SQL Pattern Matching
Wellington APAC Groundbreakers tour - SQL Pattern MatchingWellington APAC Groundbreakers tour - SQL Pattern Matching
Wellington APAC Groundbreakers tour - SQL Pattern MatchingConnor McDonald
 
Pumps, Compressors and Turbine Fault Frequency Analysis
Pumps, Compressors and Turbine Fault Frequency AnalysisPumps, Compressors and Turbine Fault Frequency Analysis
Pumps, Compressors and Turbine Fault Frequency AnalysisUniversity of Illinois,Chicago
 
Pumps, Compressors and Turbine Fault Frequency Analysis
Pumps, Compressors and Turbine Fault Frequency AnalysisPumps, Compressors and Turbine Fault Frequency Analysis
Pumps, Compressors and Turbine Fault Frequency AnalysisUniversity of Illinois,Chicago
 
Webinar: Secrets of ClickHouse Query Performance, by Robert Hodges
Webinar: Secrets of ClickHouse Query Performance, by Robert HodgesWebinar: Secrets of ClickHouse Query Performance, by Robert Hodges
Webinar: Secrets of ClickHouse Query Performance, by Robert HodgesAltinity Ltd
 
The ultimate-guide-to-sql
The ultimate-guide-to-sqlThe ultimate-guide-to-sql
The ultimate-guide-to-sqlMcNamaraChiwaye
 
Aggregating Data Using Group Functions
Aggregating Data Using Group FunctionsAggregating Data Using Group Functions
Aggregating Data Using Group FunctionsSalman Memon
 

Similar to Ctes percona live_2017 (20)

Common Table Expressions (CTE) & Window Functions in MySQL 8.0
Common Table Expressions (CTE) & Window Functions in MySQL 8.0Common Table Expressions (CTE) & Window Functions in MySQL 8.0
Common Table Expressions (CTE) & Window Functions in MySQL 8.0
 
MySQL Optimizer: What's New in 8.0
MySQL Optimizer: What's New in 8.0MySQL Optimizer: What's New in 8.0
MySQL Optimizer: What's New in 8.0
 
MySQL Optimizer Overview
MySQL Optimizer OverviewMySQL Optimizer Overview
MySQL Optimizer Overview
 
MySQL Optimizer Overview
MySQL Optimizer OverviewMySQL Optimizer Overview
MySQL Optimizer Overview
 
ClickHouse Query Performance Tips and Tricks, by Robert Hodges, Altinity CEO
ClickHouse Query Performance Tips and Tricks, by Robert Hodges, Altinity CEOClickHouse Query Performance Tips and Tricks, by Robert Hodges, Altinity CEO
ClickHouse Query Performance Tips and Tricks, by Robert Hodges, Altinity CEO
 
Webinar slides: MORE secrets of ClickHouse Query Performance. By Robert Hodge...
Webinar slides: MORE secrets of ClickHouse Query Performance. By Robert Hodge...Webinar slides: MORE secrets of ClickHouse Query Performance. By Robert Hodge...
Webinar slides: MORE secrets of ClickHouse Query Performance. By Robert Hodge...
 
ADVANCE ITT BY PRASAD
ADVANCE ITT BY PRASADADVANCE ITT BY PRASAD
ADVANCE ITT BY PRASAD
 
Beginers guide for oracle sql
Beginers guide for oracle sqlBeginers guide for oracle sql
Beginers guide for oracle sql
 
Wellington APAC Groundbreakers tour - Upgrading to the 12c Optimizer
Wellington APAC Groundbreakers tour - Upgrading to the 12c OptimizerWellington APAC Groundbreakers tour - Upgrading to the 12c Optimizer
Wellington APAC Groundbreakers tour - Upgrading to the 12c Optimizer
 
KScope19 - SQL Features
KScope19 - SQL FeaturesKScope19 - SQL Features
KScope19 - SQL Features
 
SQL.pptx
SQL.pptxSQL.pptx
SQL.pptx
 
Explain the explain_plan
Explain the explain_planExplain the explain_plan
Explain the explain_plan
 
MySQL 8.0: What Is New in Optimizer and Executor?
MySQL 8.0: What Is New in Optimizer and Executor?MySQL 8.0: What Is New in Optimizer and Executor?
MySQL 8.0: What Is New in Optimizer and Executor?
 
Wellington APAC Groundbreakers tour - SQL Pattern Matching
Wellington APAC Groundbreakers tour - SQL Pattern MatchingWellington APAC Groundbreakers tour - SQL Pattern Matching
Wellington APAC Groundbreakers tour - SQL Pattern Matching
 
Pumps, Compressors and Turbine Fault Frequency Analysis
Pumps, Compressors and Turbine Fault Frequency AnalysisPumps, Compressors and Turbine Fault Frequency Analysis
Pumps, Compressors and Turbine Fault Frequency Analysis
 
Pumps, Compressors and Turbine Fault Frequency Analysis
Pumps, Compressors and Turbine Fault Frequency AnalysisPumps, Compressors and Turbine Fault Frequency Analysis
Pumps, Compressors and Turbine Fault Frequency Analysis
 
Webinar: Secrets of ClickHouse Query Performance, by Robert Hodges
Webinar: Secrets of ClickHouse Query Performance, by Robert HodgesWebinar: Secrets of ClickHouse Query Performance, by Robert Hodges
Webinar: Secrets of ClickHouse Query Performance, by Robert Hodges
 
The ultimate-guide-to-sql
The ultimate-guide-to-sqlThe ultimate-guide-to-sql
The ultimate-guide-to-sql
 
Aggregating Data Using Group Functions
Aggregating Data Using Group FunctionsAggregating Data Using Group Functions
Aggregating Data Using Group Functions
 
Module03
Module03Module03
Module03
 

Recently uploaded

Vectors are the new JSON in PostgreSQL (SCaLE 21x)
Vectors are the new JSON in PostgreSQL (SCaLE 21x)Vectors are the new JSON in PostgreSQL (SCaLE 21x)
Vectors are the new JSON in PostgreSQL (SCaLE 21x)Jonathan Katz
 
New ThousandEyes Product Features and Release Highlights: March 2024
New ThousandEyes Product Features and Release Highlights: March 2024New ThousandEyes Product Features and Release Highlights: March 2024
New ThousandEyes Product Features and Release Highlights: March 2024ThousandEyes
 
Understanding Native Mobile App Development
Understanding Native Mobile App DevelopmentUnderstanding Native Mobile App Development
Understanding Native Mobile App DevelopmentMobulous Technologies
 
JS-Experts - Cybersecurity for Generative AI
JS-Experts - Cybersecurity for Generative AIJS-Experts - Cybersecurity for Generative AI
JS-Experts - Cybersecurity for Generative AIIvo Andreev
 
Your Vision, Our Expertise: TECUNIQUE's Tailored Software Teams
Your Vision, Our Expertise: TECUNIQUE's Tailored Software TeamsYour Vision, Our Expertise: TECUNIQUE's Tailored Software Teams
Your Vision, Our Expertise: TECUNIQUE's Tailored Software TeamsJaydeep Chhasatia
 
20240319 Car Simulator Plan.pptx . Plan for a JavaScript Car Driving Simulator.
20240319 Car Simulator Plan.pptx . Plan for a JavaScript Car Driving Simulator.20240319 Car Simulator Plan.pptx . Plan for a JavaScript Car Driving Simulator.
20240319 Car Simulator Plan.pptx . Plan for a JavaScript Car Driving Simulator.Sharon Liu
 
Streamlining Your Application Builds with Cloud Native Buildpacks
Streamlining Your Application Builds  with Cloud Native BuildpacksStreamlining Your Application Builds  with Cloud Native Buildpacks
Streamlining Your Application Builds with Cloud Native BuildpacksVish Abrams
 
Cybersecurity Challenges with Generative AI - for Good and Bad
Cybersecurity Challenges with Generative AI - for Good and BadCybersecurity Challenges with Generative AI - for Good and Bad
Cybersecurity Challenges with Generative AI - for Good and BadIvo Andreev
 
Big Data Bellevue Meetup | Enhancing Python Data Loading in the Cloud for AI/ML
Big Data Bellevue Meetup | Enhancing Python Data Loading in the Cloud for AI/MLBig Data Bellevue Meetup | Enhancing Python Data Loading in the Cloud for AI/ML
Big Data Bellevue Meetup | Enhancing Python Data Loading in the Cloud for AI/MLAlluxio, Inc.
 
Optimizing Business Potential: A Guide to Outsourcing Engineering Services in...
Optimizing Business Potential: A Guide to Outsourcing Engineering Services in...Optimizing Business Potential: A Guide to Outsourcing Engineering Services in...
Optimizing Business Potential: A Guide to Outsourcing Engineering Services in...Jaydeep Chhasatia
 
OpenChain Webinar: Universal CVSS Calculator
OpenChain Webinar: Universal CVSS CalculatorOpenChain Webinar: Universal CVSS Calculator
OpenChain Webinar: Universal CVSS CalculatorShane Coughlan
 
Enterprise Document Management System - Qualityze Inc
Enterprise Document Management System - Qualityze IncEnterprise Document Management System - Qualityze Inc
Enterprise Document Management System - Qualityze Incrobinwilliams8624
 
React 19: Revolutionizing Web Development
React 19: Revolutionizing Web DevelopmentReact 19: Revolutionizing Web Development
React 19: Revolutionizing Web DevelopmentBOSC Tech Labs
 
ERP For Electrical and Electronics manufecturing.pptx
ERP For Electrical and Electronics manufecturing.pptxERP For Electrical and Electronics manufecturing.pptx
ERP For Electrical and Electronics manufecturing.pptxAutus Cyber Tech
 
Kawika Technologies pvt ltd Software Development Company in Trivandrum
Kawika Technologies pvt ltd Software Development Company in TrivandrumKawika Technologies pvt ltd Software Development Company in Trivandrum
Kawika Technologies pvt ltd Software Development Company in TrivandrumKawika Technologies
 
Fields in Java and Kotlin and what to expect.pptx
Fields in Java and Kotlin and what to expect.pptxFields in Java and Kotlin and what to expect.pptx
Fields in Java and Kotlin and what to expect.pptxJoão Esperancinha
 
AI Embracing Every Shade of Human Beauty
AI Embracing Every Shade of Human BeautyAI Embracing Every Shade of Human Beauty
AI Embracing Every Shade of Human BeautyRaymond Okyere-Forson
 
Top Software Development Trends in 2024
Top Software Development Trends in  2024Top Software Development Trends in  2024
Top Software Development Trends in 2024Mind IT Systems
 
Watermarking in Source Code: Applications and Security Challenges
Watermarking in Source Code: Applications and Security ChallengesWatermarking in Source Code: Applications and Security Challenges
Watermarking in Source Code: Applications and Security ChallengesShyamsundar Das
 

Recently uploaded (20)

Vectors are the new JSON in PostgreSQL (SCaLE 21x)
Vectors are the new JSON in PostgreSQL (SCaLE 21x)Vectors are the new JSON in PostgreSQL (SCaLE 21x)
Vectors are the new JSON in PostgreSQL (SCaLE 21x)
 
New ThousandEyes Product Features and Release Highlights: March 2024
New ThousandEyes Product Features and Release Highlights: March 2024New ThousandEyes Product Features and Release Highlights: March 2024
New ThousandEyes Product Features and Release Highlights: March 2024
 
Understanding Native Mobile App Development
Understanding Native Mobile App DevelopmentUnderstanding Native Mobile App Development
Understanding Native Mobile App Development
 
JS-Experts - Cybersecurity for Generative AI
JS-Experts - Cybersecurity for Generative AIJS-Experts - Cybersecurity for Generative AI
JS-Experts - Cybersecurity for Generative AI
 
Your Vision, Our Expertise: TECUNIQUE's Tailored Software Teams
Your Vision, Our Expertise: TECUNIQUE's Tailored Software TeamsYour Vision, Our Expertise: TECUNIQUE's Tailored Software Teams
Your Vision, Our Expertise: TECUNIQUE's Tailored Software Teams
 
Salesforce AI Associate Certification.pptx
Salesforce AI Associate Certification.pptxSalesforce AI Associate Certification.pptx
Salesforce AI Associate Certification.pptx
 
20240319 Car Simulator Plan.pptx . Plan for a JavaScript Car Driving Simulator.
20240319 Car Simulator Plan.pptx . Plan for a JavaScript Car Driving Simulator.20240319 Car Simulator Plan.pptx . Plan for a JavaScript Car Driving Simulator.
20240319 Car Simulator Plan.pptx . Plan for a JavaScript Car Driving Simulator.
 
Streamlining Your Application Builds with Cloud Native Buildpacks
Streamlining Your Application Builds  with Cloud Native BuildpacksStreamlining Your Application Builds  with Cloud Native Buildpacks
Streamlining Your Application Builds with Cloud Native Buildpacks
 
Cybersecurity Challenges with Generative AI - for Good and Bad
Cybersecurity Challenges with Generative AI - for Good and BadCybersecurity Challenges with Generative AI - for Good and Bad
Cybersecurity Challenges with Generative AI - for Good and Bad
 
Big Data Bellevue Meetup | Enhancing Python Data Loading in the Cloud for AI/ML
Big Data Bellevue Meetup | Enhancing Python Data Loading in the Cloud for AI/MLBig Data Bellevue Meetup | Enhancing Python Data Loading in the Cloud for AI/ML
Big Data Bellevue Meetup | Enhancing Python Data Loading in the Cloud for AI/ML
 
Optimizing Business Potential: A Guide to Outsourcing Engineering Services in...
Optimizing Business Potential: A Guide to Outsourcing Engineering Services in...Optimizing Business Potential: A Guide to Outsourcing Engineering Services in...
Optimizing Business Potential: A Guide to Outsourcing Engineering Services in...
 
OpenChain Webinar: Universal CVSS Calculator
OpenChain Webinar: Universal CVSS CalculatorOpenChain Webinar: Universal CVSS Calculator
OpenChain Webinar: Universal CVSS Calculator
 
Enterprise Document Management System - Qualityze Inc
Enterprise Document Management System - Qualityze IncEnterprise Document Management System - Qualityze Inc
Enterprise Document Management System - Qualityze Inc
 
React 19: Revolutionizing Web Development
React 19: Revolutionizing Web DevelopmentReact 19: Revolutionizing Web Development
React 19: Revolutionizing Web Development
 
ERP For Electrical and Electronics manufecturing.pptx
ERP For Electrical and Electronics manufecturing.pptxERP For Electrical and Electronics manufecturing.pptx
ERP For Electrical and Electronics manufecturing.pptx
 
Kawika Technologies pvt ltd Software Development Company in Trivandrum
Kawika Technologies pvt ltd Software Development Company in TrivandrumKawika Technologies pvt ltd Software Development Company in Trivandrum
Kawika Technologies pvt ltd Software Development Company in Trivandrum
 
Fields in Java and Kotlin and what to expect.pptx
Fields in Java and Kotlin and what to expect.pptxFields in Java and Kotlin and what to expect.pptx
Fields in Java and Kotlin and what to expect.pptx
 
AI Embracing Every Shade of Human Beauty
AI Embracing Every Shade of Human BeautyAI Embracing Every Shade of Human Beauty
AI Embracing Every Shade of Human Beauty
 
Top Software Development Trends in 2024
Top Software Development Trends in  2024Top Software Development Trends in  2024
Top Software Development Trends in 2024
 
Watermarking in Source Code: Applications and Security Challenges
Watermarking in Source Code: Applications and Security ChallengesWatermarking in Source Code: Applications and Security Challenges
Watermarking in Source Code: Applications and Security Challenges
 

Ctes percona live_2017

  • 1. Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | MySQL 8.0: Common Table Expressions Guilhem Bichot – Lead Software Engineer MySQL Optimizer Team, Oracle
  • 2. Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | Who ● With MySQL AB / Sun / Oracle since 2002 ● Coder on the Server from 4.0 to 8.0 ● Replication, on-line backup, Maria storage engine, optimizer... ● Recent work: – 5.7: for queries with GROUP BY, sql_mode=only_full_group_by smarter and enabled by default (see blog links at end) – 8.0: [recursive] common table expressions ● Guilhem.bichot@<theBigO> 2
  • 3. Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | Program Agenda Non-recursive common table expressions Recursive common table expressions 1 2 3
  • 4. Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | Program Agenda Non-recursive common table expressions Recursive common table expressions 1 2 4
  • 5. Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | What is a Common Table Expression? • In official MySQL 8.0.1+. • A derived table is a subquery in the FROM clause SELECT … FROM (subquery) AS derived, t1 … • A Common Table Expression (CTE) is just like a derived table, but its declaration is moved to before the query WITH cte AS (subquery) SELECT … FROM cte, t1 … • SQL:99: a named (sub)query, “Query Name”. MSSQL, PG: A “Table Expression” (~subquery) which is put in “Common”. ORCL: a factored out subquery, “Subquery Factoring”. 5
  • 6. Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | How do I create a CTE? WITH cte_name [( <list of column names> )] AS ( SELECT ... # Definition ) [, <any number of other CTE definitions> ] <SELECT/UPDATE/DELETE statement, referencing the CTEs> 6
  • 7. Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | Giving names to columns of the CTE ● Default naming: from selected expressions WITH cte AS (SELECT a+2, b FROM t1) SELECT cte.`a+2` + 10 FROM cte; ● Custom naming, alt. 1: give alias to the selected expressions WITH cte AS (SELECT a+2 AS a, b FROM t1) SELECT cte.a + 10 FROM cte; ● Custom naming, alt. 2: list names right after CTE's name WITH cte(a, b) AS (SELECT a+2, b FROM t2) SELECT cte.a + 10 FROM cte; – Side-note: also added same feature to derived table: SELECT … FROM (SELECT a+2,b …) AS derived(a,b); (views already had that: CREATE VIEW v(a,b) AS SELECT ...) 7
  • 8. Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | Two strategies of evaluation for a CTE WITH cte AS (SELECT a FROM t1 WHERE a<5) SELECT * FROM cte, t2 WHERE cte.a>3; ● “cte” may be materialized: – Evaluate SELECT a FROM t1 WHERE a<5 – Store that in transient temporary table named “cte” with column named “a” – Do: SELECT * FROM cte, t2 WHERE cte.a>3; – Optimizer may create indexes on the temporary table to speed up predicates like cte.a=t2.b (look for “auto_key” in “key” column in EXPLAIN). ● Or “cte” may be merged: – SELECT * FROM t1, t2 WHERE t1.a>3 AND t1.a<5; – good if outer predicate cte.a>3 is selective while inner a<5 is not. 8
  • 9. Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | Two strategies of evaluation for a CTE WITH cte AS (SELECT a FROM t1 WHERE a<5) SELECT * FROM cte, t2 WHERE cte.a>3; ● Choice between the two strategies, materialization vs merging: – Heuristics – Technical constraints prevent merging ● e.g. if CTE contains GROUP BY or is recursive: always materialized – Hint: ● /*+ MERGE(cte) */ ● /*+ NO_MERGE(cte) */ ● Set @@optimizer_switch=”derived_merge=on|off” ● Applicable to CTEs, views and derived tables 9
  • 10. Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | CTE can be local to subquery WITH cte AS (SELECT a+2 AS a, b FROM t2) SELECT * FROM t1 WHERE t1.a IN (SELECT a * 3 FROM cte); # Scope: “cte” is visible to top SELECT vs SELECT * FROM t1 WHERE t1.a IN (WITH cte AS (SELECT a+2 AS a, b FROM t2) SELECT a * 3 FROM cte); # Scope: “cte” is not visible to top SELECT 10
  • 11. Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | CTEs allowed in other statements Can use CTE as read-only source to update other tables: WITH cte AS (SELECT a+2 AS a, b FROM t2) UPDATE t1, cte SET t1.a=cte.b + 10 WHERE t1.a = cte.a; WITH cte AS (SELECT a+2 AS a, b FROM t2) DELETE t1 FROM t1, cte WHERE t1.a = cte.a; INSERT INTO t2 WITH cte AS (SELECT a+2 AS a, b FROM t2) SELECT * FROM cte; 11
  • 12. Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | Common Table Expression vs. Derived Table Better readability Can be referenced multiple times Easier chaining Improved performance 12
  • 13. Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | Better readability • Derived table: SELECT dt.a FROM t1 LEFT JOIN ((SELECT … FROM …) AS dt JOIN t2 ON …) ON … – If reading top to bottom... – … You first see dt.a … so what's dt ? – … Read on, it's deeply nested somewhere... • CTE: WITH dt AS (SELECT ... FROM ...) SELECT dt.a FROM t1 LEFT JOIN (dt JOIN t2 ON ...) ON … 13
  • 14. Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | Easier chaining • Derived table cannot refer to a neighbour derived table: SELECT … FROM (SELECT … FROM …) AS d1, (SELECT … FROM d1 …) AS d2 … ERROR: 1146 (42S02): Table ‘db.d1’ doesn’t exist • Workaround: nest d1 in d2 SELECT … FROM (SELECT … FROM (SELECT … FROM …) AS d1 …) AS d2 • Works but leads to nesting, is not very readable 14
  • 15. Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | Easier chaining • CTE can refer to a neighbour CTE: WITH d1 AS (SELECT … FROM …), d2 AS (SELECT … FROM d1 …) SELECT FROM d1, d2 … ● More readable this way 15
  • 16. Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | Example of chaining WITH sales_by_month(month,total) AS # first CTE: one row per month, with amount sold on all days of month (SELECT MONTH(day_of_sale), SUM(amount) FROM sales_days WHERE YEAR(day_of_sale)=2017 GROUP BY MONTH(day_of_sale)), best_month(month, total, award) AS # second CTE: best month (SELECT month, total, "best" FROM sales_by_month WHERE total=(SELECT MAX(total) FROM sales_by_month)), worst_month(month, total, award) AS # 3rd CTE: worst month (SELECT month, total, "worst" FROM sales_by_month WHERE total=(SELECT MIN(total) FROM sales_by_month)) # Now show best, worst and difference: SELECT * FROM best_month UNION ALL SELECT * FROM worst_month UNION ALL SELECT NULL, bm.total - wm.total, “diff” FROM best_month bm, worst_month wm; 16
  • 17. Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | Example of chaining Result: +-------+-------+-------+ | month | total | award | +-------+-------+-------+ | 1 | 300 | best | | 3 | 11 | worst | | NULL | 289 | diff | +-------+-------+-------+ 17
  • 18. Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | Can be referenced multiple times • If you want to make N references to a derived table you must write N definitions: in the previous query you would need to write (copy) eight times the definition of sales_by_month • CTE can be referenced multiple times: sales_by_month is referenced four times, best_month two times... 18
  • 19. Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | Better Performance: DBT3 (TPC-H) Query 15 CREATE VIEW revenue0 (r_supplier_no, r_total_revenue) AS SELECT l_suppkey, SUM(l_extendedprice * (1-l_discount)) FROM  lineitem WHERE l_shipdate >= '1996-07-01'  AND l_shipdate < DATE_ADD('1996-07-01‘, INTERVAL '90' day) GROUP BY  l_suppkey; SELECT s_suppkey, s_name, s_address, s_phone, r_total_revenue FROM supplier, revenue0 WHERE s_suppkey = r_supplier_no AND r_total_revenue = (SELECT MAX(r_total_revenue) FROM revenue0) ORDER BY s_suppkey; “Top Supplier Query”
  • 20. Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | Materialization of view DBT-3 Query 15 ORDER JOIN Supplier (eq_ref) GROUP Lineitem (range) Materialize GROUP Lineitem (range) Materialize SELECT S u b q u e r y Revenue0 Revenue0 W H ERE FROM
  • 21. Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | DBT-3 Query 15 EXPLAIN CTE id select type table type possible keys key rows 1 PRIMARY <derived3> ALL NULL NULL 4801074 1 PRIMARY supplier eq_ref PRIMARY PRIMARY 1 3 DERIVED lineitem range i_l_shipdate, ... i_l_shipdate 4801074 2 SUBQUERY <derived4> ALL NULL NULL 4801074 4 DERIVED lineitem range i_l_shipdate, ... i_l_shipdate 4801074
  • 22. Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | Rewritten to use a CTE WITH revenue0 (r_supplier_no, r_total_revenue) AS (SELECT l_suppkey, SUM(l_extendedprice * (1-l_discount)) FROM  lineitem WHERE l_shipdate >= '1996-07-01'  AND l_shipdate < DATE_ADD('1996-07-01‘, INTERVAL '90' day) GROUP BY  l_suppkey) /* same definition as view's */ SELECT s_suppkey, s_name, s_address, s_phone, r_total_revenue FROM supplier, revenue0 WHERE s_suppkey = r_supplier_no AND r_total_revenue = (SELECT MAX(r_total_revenue) FROM revenue0) ORDER BY s_suppkey;
  • 23. Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | DBT-3 Query 15, CTE EXPLAIN CTE id select type table type possible keys key rows 1 PRIMARY <derived2> ALL NULL NULL 4801074 1 PRIMARY supplier eq_ref PRIMARY PRIMARY 1 3 SUBQUERY <derived2> ALL NULL NULL 4801074 2 DERIVED lineitem range i_l_shipdate, ... i_l_shipdate 4801074
  • 24. Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | DBT-3 Query 15 Materialization of CTE ORDER JOIN Supplier (eq_ref) GROUP Lineitem (range) Materialize SELECT S u b q u e r y Revenue0 W H ERE FROM
  • 25. Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | DBT-3 Query 15 25 Query Performance View CTE 0 2 4 6 8 10 12 14 16 18 Query Execution Time (seconds)
  • 26. Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | Single-materialized CTE • N references but one temporary table • Reduces disk usage, memory usage, execution time • Possibly a different auto_key index for each reference – WITH cte AS (…) SELECT … FROM cte AS cte1, cte AS cte2 WHERE cte1.a=3 AND cte2.b=5 – Automatically adds index on cte.a and index on cte.b – In EXPLAIN: <auto_key0>, <auto_key1>, … • Can be better than CTE merging, if outer predicates are not very selective or base tables in CTE's subquery are poorly indexed 26
  • 27. Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | Single-materialized CTE • Handy if CTE contains some random value to be used twice • Lottery: find all rows of t1 where column “age” is +-5 around a certain random threshold, and also display the chosen threshold. • WITH cte(rnd) AS (SELECT ROUND(RAND()*125) SELECT t1.name, cte.rnd FROM cte, t1 WHERE t1.age BETWEEN cte.rnd-5 AND cte.rnd+5 • Single materialization gives same value to all three uses of cte.rnd. 27
  • 28. Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | Program Agenda Non-recursive common table expressions Recursive common table expressions 1 2 28
  • 29. Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | Recursive CTE • A recursive CTE refers to itself in the defining subquery • Always materialized into transient temporary table • Seed SELECT is executed once to create the first data subset • Recursive SELECT is repeatedly executed to return new subsets of data: to the eyes of iteration N+1, “cte” = subset produced by iteration N, and only that. 29 WITH RECURSIVE cte AS ( SELECT ... FROM table_name /* "seed" SELECT */ UNION [DISTINCT|ALL] SELECT ... FROM cte, table_name /* recursive SELECT */ WHERE …) SELECT ... FROM cte; /* outer query */
  • 30. Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | Recursive CTE • The process stops when an iteration does not generate any row • The union of all subsets is stored into a transient temporary table; to the eyes of the outer query, “cte” = that table. • Useful to – Generate series (start:end:step) – Explore hierarchies (parent/child, part/subpart, trees), connections (graphs) 30
  • 31. Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | Recursive CTE 31 A simple example : start:end:step sequence of values Print 1 to 10 : WITH RECURSIVE cte AS ( SELECT 1 AS a UNION ALL SELECT 1+a FROM cte WHERE a<10 ) SELECT * FROM cte; a 1 # Seed SELECT 2 # Recursive SELECT, it. 1 3 # Recursive SELECT, it. 2 4 5 6 7 8 9 10 ∅... because 10<10 is false
  • 32. Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | Recursive CTE 32 Note the fixpoint The final 'cte' satisfies : cte == ( SELECT 1 AS a UNION ALL SELECT 1+a FROM cte WHERE a<10 ) a 1 2 3 4 5 6 7 8 9 10 a 1 a 1 2 3 4 5 6 7 8 9 10 a 2 3 4 5 6 7 8 9 10 a 1 2 3 4 5 6 7 8 9 10 cte WHERE a<10 a+1 UNION ALL =cte!
  • 33. Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | Recursive CTE • Find the fixpoint(s) i.e. the solution(s) to X = F(X), X is a set • Assuming F is monotonic - if Y contains X, F(Y) contains F(X) • F(∅), F(F(∅)), F(F(F(∅))), … will stagnate at some point • So the fixpoint exists and we found it • Requirement 1: F must be monotonic • But iterating F over growing sets is costly • Optimization: iterate F over new rows only – Works only if F doesn't join X with itself (linear recursion) 33 Fixpoint (~10 years of research & discussion in SQL committee)
  • 34. Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | Recursive CTE • A recursive SELECT must reference the CTE – in its FROM clause, and only once (or miss “new JOIN old” ⇒linear) – not in any subquery (NOT EXISTS (subquery) ⇒monotonic) – not as the right table of a left join (row disappears ⇒monotonic) ● A recursive SELECT must not contain – GROUP BY or aggregate/window functions (SUM, LEAD) (aggregated SUM changes ⇒monotonic) – ORDER BY, LIMIT or DISTINCT (MySQL-specific restriction) ● My one-line rule: an iteration handles one row in isolation. 34 SQL-standard restrictions
  • 35. Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | Recursive CTE 35 Implementation: greedy reading over an open-ended tmp table 1 Seed done Recursive SELECT………………………………………………………………………………... 1 1 2 1 2 1 2 3 Read pointer Write pointer 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10 And So on Theory : run the recursive SELECT ten times ; implementation: run it once. FIFOqueue
  • 36. Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | Recursive CTE • Numbers 1-10 is a one-level recursive sequence – value N+1 = function of value N • Two-level recursive sequence is possible – value N+2 = function of value N and value N+1 – like Fibonacci numbers – However “an iteration handles one row in isolation” – So let the row for N+1 also contain a “recall” of N, in an extra column. • With INSERT SELECT, the sequence can be stored in a table 36
  • 37. Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | Date sequence 37 Missing dates SELECT orderdate, SUM(totalprice) sales FROM orders GROUP BY orderdate ORDER BY orderdate; +------------+-----------+ | orderdate | sales | +------------+-----------+ | 2016-09-01 | 43129.83 | | 2016-09-03 | 218347.61 | | 2016-09-04 | 142568.40 | | 2016-09-05 | 299244.83 | | 2016-09-07 | 185991.79 | +------------+-----------+ Missing September 2nd and 6th...
  • 38. Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | Date sequence 38 All dates WITH RECURSIVE dates(date) AS ( SELECT '2016-09-01' UNION ALL SELECT DATE_ADD(date, INTERVAL 1 DAY) FROM dates WHERE date < '2016-09-07‘ ) SELECT dates.date, COALESCE(SUM(totalprice), 0) sales FROM dates LEFT JOIN orders ON dates.date = orders.orderdate GROUP BY dates.date ORDER BY dates.date; +------------+-----------+ | date | sales | +------------+-----------+ | 2016-09-01 | 43129.83 | | 2016-09-02 | 0.00 | | 2016-09-03 | 218347.61 | | 2016-09-04 | 142568.40 | | 2016-09-05 | 299244.83 | | 2016-09-06 | 0.00 | | 2016-09-07 | 185991.79 | +------------+-----------+
  • 39. Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | Hierarchy Traversal 39 Employee database CREATE TABLE employees ( id INT PRIMARY KEY, name VARCHAR(100), manager_id INT, FOREIGN KEY (manager_id) REFERENCES employees(id) ); INSERT INTO employees VALUES (333, "Yasmina", NULL), # CEO (198, "John", 333), # J reports to Y (692, "Tarek", 333), (29, "Pedro", 198), (4610, "Sarah", 29), (72, "Pierre", 29), (123, "Adil", 692);
  • 40. Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | Hierarchy Traversal 40 Employee database Yasmina (333) John (198) Tarek (692) Pedro (29) Sarah (4610) Pierre (72) Adil (123) (BF)(DF)(NO)
  • 41. Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | Hierarchy Traversal 41 How to walk the tree Yasmina (333) John (198) Tarek (692) Pedro (29) Sarah (4610) Pierre (72) Adil (123) Seed Iteration 1 Iteration 2 Iteration 3 Iteration 4 ∅
  • 42. Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | Hierarchy Traversal 42 Find reporting chain for every employee WITH RECURSIVE emp_ext (id, name, path) AS ( SELECT id, name, CAST(id AS CHAR(200)) FROM employees WHERE manager_id IS NULL UNION ALL SELECT s.id, s.name, CONCAT(m.path, ",", s.id) FROM emp_ext m JOIN employees s ON m.id=s.manager_id ) SELECT * FROM emp_ext ; id name path 333 Yasmina 333 198 John 333,198 692 Tarek 333,692 29 Pedro 333,198,29 123 Adil 333,692,123 4610 Sarah 333,198,29,4610 72 Pierre 333,198,29,72 ∅ Note : no guaranteed output order (tree)
  • 43. Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | Hierarchy Traversal 43 Reporting chain, depth first: “children” before “brothers” WITH RECURSIVE emp_ext (id, name, path) AS ( SELECT id, name, CAST(id AS CHAR(200)) FROM employees WHERE manager_id IS NULL UNION ALL SELECT s.id, s.name, CONCAT(m.path, ",", s.id) FROM emp_ext m JOIN employees s ON m.id=s.manager_id ) SELECT * FROM emp_ext ORDER BY path; id name path 333 Yasmina 333 198 John 333,198 29 Pedro 333,198,29 4610 Sarah 333,198,29,4610 72 Pierre 333,198,29,72 692 Tarek 333,692 123 Adil 333,692,123 (tree)
  • 44. Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | Hierarchy Traversal 44 Reporting chain, breadth first: “brothers” before “children” WITH RECURSIVE emp_ext (id, name, path, lvl) AS ( SELECT id, name, CAST(id AS CHAR(200)), 1 FROM employees WHERE manager_id IS NULL UNION ALL SELECT s.id, s.name, CONCAT(m.path, ",", s.id), m.lvl + 1 FROM emp_ext m JOIN employees s ON m.id=s.manager_id ) SELECT * FROM emp_ext ORDER BY lvl; id name path lvl 333 Yasmina 333 1 198 John 333,198 2 692 Tarek 333,692 2 29 Pedro 333,198,29 3 123 Adil 333,692,123 3 4610 Sarah 333,198,29,4610 4 72 Pierre 333,198,29,72 4 (tree)
  • 45. Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | Recursive CTE – complete syntax WITH RECURSIVE cte_name [ list of column names ] AS ( SELECT ... <-- specifies initial set UNION [DISTINCT|ALL] SELECT ... <-- specifies initial set UNION [DISTINCT|ALL] ... SELECT ... <-- specifies how to derive new rows UNION [DISTINCT|ALL] SELECT ... <-- specifies how to derive new rows ... ) [, any number of other CTE definitions ] <SELECT/UPDATE/DELETE statement, referencing the CTEs> 45
  • 46. Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | Recursive CTE – goodies! ● UNION DISTINCT to add only non-duplicate rows – Think: walking a graph to find “all direct and indirect connections of A” (a.k.a. build the transitive closure of A): A->B->C->A – Several well-known commercial DBMSs don't support UNION DISTINCT ● Flagging abnormal cycles: – Leverage the PATH column – A new row is closing a cycle if it's already in the PATH (test with FIND_IN_SET) ● More tips about cycles: see my blogs (last slides) 46
  • 47. Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | Recursive CTE – goodies! ● Runaway query: – Forgot the WHERE in recursive SELECT, or typed it wrong (a<0 in lieu of a>0) – Or: unexpected cycle in my data ● You're covered: WITH RECURSIVE cte AS ( SELECT 1 AS a UNION ALL SELECT 1+a FROM cte ) SELECT * FROM cte; ERROR HY000: Recursive query aborted after 1001 iterations. Try increasing @@cte_max_recursion_depth to a larger value. 47
  • 48. Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | Want to try it out? • Available since version 8.0.1 • Install MySQL Server 8.0.3 (Release Candidate) – Bonus over 8.0.1: ● @@cte_max_recursion_depth variable ● A couple of bugfixes ● No known bugs 48
  • 49. Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | Want to learn more? • My four blog posts: http://mysqlserverteam.com/mysql-8-0-labs-recursive-common-table-ex pressions-in-mysql-ctes • https://dev.mysql.com/doc/refman/8.0/en/with.html • MySQL Optimizer & Parser forum: http://forums.mysql.com/list.php?115 • Shameless plug ☺ only_full_group_by improvements in 5.7: http://mysqlserverteam.com/mysql-5-7-only_full_group_by- improved-recognizing-functional-dependencies-enabled-by- default/
  • 50. Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | Safe Harbor Statement The preceding is intended to outline our general product direction. It is intended for information purposes only, and may not be incorporated into any contract. It is not a commitment to deliver any material, code, or functionality, and should not be relied upon in making purchasing decisions. The development, release, and timing of any features or functionality described for Oracle’s products remains at the sole discretion of Oracle. 50

Editor's Notes

  1. &amp;lt;numéro&amp;gt;
  2. &amp;lt;numéro&amp;gt;
  3. &amp;lt;numéro&amp;gt;
  4. &amp;lt;numéro&amp;gt;
  5. notes &amp;lt;numéro&amp;gt;
  6. notes &amp;lt;numéro&amp;gt;
  7. notes &amp;lt;numéro&amp;gt;
  8. Notes &amp;lt;numéro&amp;gt;
  9. Notes &amp;lt;numéro&amp;gt;
  10. 4 CTEs, all with a single column called txt Cte1: One row: This Cte2: One row: This is a Cte3: Three rows Cte4: &amp;lt;numéro&amp;gt;
  11. 4 CTEs, all with a single column called txt Cte1: One row: This Cte2: One row: This is a Cte3: Three rows Cte4: &amp;lt;numéro&amp;gt;
  12. notes &amp;lt;numéro&amp;gt;
  13. 0:40/8:20 We will look closer at one of the queries that benefits from DS-MRR. This query finds the suppliers that provides most revenue. The query uses a view to find the revenue from each supplier in a given quarter. And based on that he finds the ones with the maximum revenue. We have an index on the shipdate column. Hence, index range scan will be used here. View which has a range criteria applicable for MRR View used both in join and sub-query &amp;lt;numéro&amp;gt;
  14. 0:20/8:40 In other words, we will materialize the view twice using a range scan on the Lineitem table before we join the rows, matching the subquery, with the supplier table. &amp;lt;numéro&amp;gt;
  15. Let us start with data access for single-table queries. Ref access is an access method for reading all rows with a given key value using an index. In otherwords, Index look-up The top example shows a query where we are looking up a customer by the customer key which is the primary key of the customer table. EXPLAIN shows that the access type is const. This means that we will be reading from a unique index, and max one row will be returned. It is called const because such look-ups will be done during the optimization of the query. Hence, the column values will be constant during execution. The possible_keys column of EXPLAIN shows the candidate indexes, and the key column show which index is actually selected. In this case, the primary index is the only candidate. In the bottom example, we want to find all orders for a given date. EXPLAIN shows that the access type is ref. This means that we will be reading from a non-unique index or a prefix of an index Hence, multiple rows may be returned. The rows columns shows that the estimated number of rows is 6272 in this case. &amp;lt;numéro&amp;gt;
  16. 0:40/8:20 We will look closer at one of the queries that benefits from DS-MRR. This query finds the suppliers that provides most revenue. The query uses a view to find the revenue from each supplier in a given quarter. And based on that he finds the ones with the maximum revenue. We have an index on the shipdate column. Hence, index range scan will be used here. View which has a range criteria applicable for MRR View used both in join and sub-query &amp;lt;numéro&amp;gt;
  17. Let us start with data access for single-table queries. Ref access is an access method for reading all rows with a given key value using an index. In otherwords, Index look-up The top example shows a query where we are looking up a customer by the customer key which is the primary key of the customer table. EXPLAIN shows that the access type is const. This means that we will be reading from a unique index, and max one row will be returned. It is called const because such look-ups will be done during the optimization of the query. Hence, the column values will be constant during execution. The possible_keys column of EXPLAIN shows the candidate indexes, and the key column show which index is actually selected. In this case, the primary index is the only candidate. In the bottom example, we want to find all orders for a given date. EXPLAIN shows that the access type is ref. This means that we will be reading from a non-unique index or a prefix of an index Hence, multiple rows may be returned. The rows columns shows that the estimated number of rows is 6272 in this case. &amp;lt;numéro&amp;gt;
  18. 0:20/8:40 In other words, we will materialize the view twice using a range scan on the Lineitem table before we join the rows, matching the subquery, with the supplier table. &amp;lt;numéro&amp;gt;
  19. &amp;lt;numéro&amp;gt;
  20. If non-recursive CTE means ease of use and better performance, recursive CTE actually allows developers to easily achieve something is not easily achievable by other means. The parenthesized &amp;quot;(SELECT ... UNION ALL SELECT ...)&amp;quot; has two query blocks. The first is the &amp;quot;non-recursive&amp;quot; (also known as &amp;quot;anchor&amp;quot; or &amp;quot;seed&amp;quot; in some other products), which is what one &amp;quot;starts with&amp;quot;. The second is the &amp;quot;recursive&amp;quot; one, which explains how the DBMS navigates from the seed&amp;apos;s result. The &amp;quot;recursive&amp;quot; one references the CTE. The &amp;quot;non-recursive&amp;quot; doesn&amp;apos;t. Execution does like this: - non-recursive query block is evaluated, result goes into internal tmp table &amp;quot;cte&amp;quot; - if no rows, exit - (A): recursive query block is evaluated over cte&amp;apos;s lastly produced rows, and it produces new rows which go into &amp;quot;cte&amp;quot; (appended to previous rows: UNION ALL) - if the last step didn&amp;apos;t produce new rows, exit - goto (A) This algorithm is good to traverse a hierarchy: the non-recursive query block returns the top parent, recursive query block&amp;apos;s first run returns children of top parent, second run returns children of those children, etc, until no more offspring. &amp;lt;numéro&amp;gt;
  21. If non-recursive CTE means ease of use and better performance, recursive CTE actually allows developers to easily achieve something is not easily achievable by other means. The parenthesized &amp;quot;(SELECT ... UNION ALL SELECT ...)&amp;quot; has two query blocks. The first is the &amp;quot;non-recursive&amp;quot; (also known as &amp;quot;anchor&amp;quot; or &amp;quot;seed&amp;quot; in some other products), which is what one &amp;quot;starts with&amp;quot;. The second is the &amp;quot;recursive&amp;quot; one, which explains how the DBMS navigates from the seed&amp;apos;s result. The &amp;quot;recursive&amp;quot; one references the CTE. The &amp;quot;non-recursive&amp;quot; doesn&amp;apos;t. Execution does like this: - non-recursive query block is evaluated, result goes into internal tmp table &amp;quot;cte&amp;quot; - if no rows, exit - (A): recursive query block is evaluated over cte&amp;apos;s lastly produced rows, and it produces new rows which go into &amp;quot;cte&amp;quot; (appended to previous rows: UNION ALL) - if the last step didn&amp;apos;t produce new rows, exit - goto (A) This algorithm is good to traverse a hierarchy: the non-recursive query block returns the top parent, recursive query block&amp;apos;s first run returns children of top parent, second run returns children of those children, etc, until no more offspring. &amp;lt;numéro&amp;gt;
  22. &amp;lt;numéro&amp;gt;
  23. If non-recursive CTE means ease of use and better performance, recursive CTE actually allows developers to easily achieve something is not easily achievable by other means. The parenthesized &amp;quot;(SELECT ... UNION ALL SELECT ...)&amp;quot; has two query blocks. The first is the &amp;quot;non-recursive&amp;quot; (also known as &amp;quot;anchor&amp;quot; or &amp;quot;seed&amp;quot; in some other products), which is what one &amp;quot;starts with&amp;quot;. The second is the &amp;quot;recursive&amp;quot; one, which explains how the DBMS navigates from the seed&amp;apos;s result. The &amp;quot;recursive&amp;quot; one references the CTE. The &amp;quot;non-recursive&amp;quot; doesn&amp;apos;t. Execution does like this: - non-recursive query block is evaluated, result goes into internal tmp table &amp;quot;cte&amp;quot; - if no rows, exit - (A): recursive query block is evaluated over cte&amp;apos;s lastly produced rows, and it produces new rows which go into &amp;quot;cte&amp;quot; (appended to previous rows: UNION ALL) - if the last step didn&amp;apos;t produce new rows, exit - goto (A) This algorithm is good to traverse a hierarchy: the non-recursive query block returns the top parent, recursive query block&amp;apos;s first run returns children of top parent, second run returns children of those children, etc, until no more offspring. &amp;lt;numéro&amp;gt;
  24. If non-recursive CTE means ease of use and better performance, recursive CTE actually allows developers to easily achieve something is not easily achievable by other means. The parenthesized &amp;quot;(SELECT ... UNION ALL SELECT ...)&amp;quot; has two query blocks. The first is the &amp;quot;non-recursive&amp;quot; (also known as &amp;quot;anchor&amp;quot; or &amp;quot;seed&amp;quot; in some other products), which is what one &amp;quot;starts with&amp;quot;. The second is the &amp;quot;recursive&amp;quot; one, which explains how the DBMS navigates from the seed&amp;apos;s result. The &amp;quot;recursive&amp;quot; one references the CTE. The &amp;quot;non-recursive&amp;quot; doesn&amp;apos;t. Execution does like this: - non-recursive query block is evaluated, result goes into internal tmp table &amp;quot;cte&amp;quot; - if no rows, exit - (A): recursive query block is evaluated over cte&amp;apos;s lastly produced rows, and it produces new rows which go into &amp;quot;cte&amp;quot; (appended to previous rows: UNION ALL) - if the last step didn&amp;apos;t produce new rows, exit - goto (A) This algorithm is good to traverse a hierarchy: the non-recursive query block returns the top parent, recursive query block&amp;apos;s first run returns children of top parent, second run returns children of those children, etc, until no more offspring. &amp;lt;numéro&amp;gt;
  25. Let us start with a simple example, print numbers from 1 to 10 with recursive cte as ( select 1 as a union all select 1+a from cte where a&amp;lt;10) select * from cte; prints 1 to 10. &amp;lt;numéro&amp;gt;
  26. Let us start with a simple example, print numbers from 1 to 10 with recursive cte as ( select 1 as a union all select 1+a from cte where a&amp;lt;10) select * from cte; prints 1 to 10. &amp;lt;numéro&amp;gt;
  27. Note that this restriction is only for the recursive select, not the non-recursive/seed/anchor SELECT Of course, it can additionally reference other tables than the CTE and join them with the CTE. &amp;lt;numéro&amp;gt;
  28. Note that this restriction is only for the recursive select, not the non-recursive/seed/anchor SELECT Of course, it can additionally reference other tables than the CTE and join them with the CTE. &amp;lt;numéro&amp;gt;
  29. Note that this restriction is only for the recursive select, not the non-recursive/seed/anchor SELECT Of course, it can additionally reference other tables than the CTE and join them with the CTE. &amp;lt;numéro&amp;gt;
  30. If non-recursive CTE means ease of use and better performance, recursive CTE actually allows developers to easily achieve something is not easily achievable by other means. The parenthesized &amp;quot;(SELECT ... UNION ALL SELECT ...)&amp;quot; has two query blocks. The first is the &amp;quot;non-recursive&amp;quot; (also known as &amp;quot;anchor&amp;quot; or &amp;quot;seed&amp;quot; in some other products), which is what one &amp;quot;starts with&amp;quot;. The second is the &amp;quot;recursive&amp;quot; one, which explains how the DBMS navigates from the seed&amp;apos;s result. The &amp;quot;recursive&amp;quot; one references the CTE. The &amp;quot;non-recursive&amp;quot; doesn&amp;apos;t. Execution does like this: - non-recursive query block is evaluated, result goes into internal tmp table &amp;quot;cte&amp;quot; - if no rows, exit - (A): recursive query block is evaluated over cte&amp;apos;s lastly produced rows, and it produces new rows which go into &amp;quot;cte&amp;quot; (appended to previous rows: UNION ALL) - if the last step didn&amp;apos;t produce new rows, exit - goto (A) This algorithm is good to traverse a hierarchy: the non-recursive query block returns the top parent, recursive query block&amp;apos;s first run returns children of top parent, second run returns children of those children, etc, until no more offspring. &amp;lt;numéro&amp;gt;
  31. Let us start with a simple example, print numbers from 1 to 10 with recursive cte as ( select 1 as a union all select 1+a from cte where a&amp;lt;10) select * from cte; prints 1 to 10. &amp;lt;numéro&amp;gt;
  32. Let us start with a simple example, print numbers from 1 to 10 with recursive cte as ( select 1 as a union all select 1+a from cte where a&amp;lt;10) select * from cte; prints 1 to 10. &amp;lt;numéro&amp;gt;
  33. CREATE TABLE EMPLOYEES ( ID INT PRIMARY KEY, NAME VARCHAR(100), MANAGER_ID INT, INDEX (MANAGER_ID), FOREIGN KEY (MANAGER_ID) REFERENCES EMPLOYEES(ID) ); INSERT INTO EMPLOYEES VALUES (333, &amp;quot;Yasmina&amp;quot;, NULL), # Yasmina is the CEO (as her manager_id is NULL) (198, &amp;quot;John&amp;quot;, 333), # John is 198 and reports to 333 (=Yasmina) (692, &amp;quot;Tarek&amp;quot;, 333), (29, &amp;quot;Pedro&amp;quot;, 198), (4610, &amp;quot;Sarah&amp;quot;, 29), (72, &amp;quot;Pierre&amp;quot;, 29), (123, &amp;quot;Adil&amp;quot;, 692); # Give me the org chart with the management chain for every employee (= the path from CEO to employee): WITH RECURSIVE EMPLOYEES_EXTENDED (ID, NAME, PATH) AS ( SELECT ID, NAME, CAST(ID AS CHAR(200)) FROM EMPLOYEES WHERE MANAGER_ID IS NULL UNION ALL SELECT S.ID, S.NAME, CONCAT(M.PATH, &amp;quot;,&amp;quot;, S.ID) FROM EMPLOYEES_EXTENDED M JOIN EMPLOYEES S ON M.ID=S.MANAGER_ID ) SELECT * FROM EMPLOYEES_EXTENDED ORDER BY PATH; ID NAME PATH Yasmina 333 198 John 333,198 29 Pedro 333,198,29 4610 Sarah 333,198,29,4610 # Sarah-&amp;gt;Pedro-&amp;gt;John-&amp;gt;Yasmina 72 Pierre 333,198,29,72 692 Tarek 333,692 123 Adil 333,692,123 &amp;lt;numéro&amp;gt;
  34. CREATE TABLE EMPLOYEES ( ID INT PRIMARY KEY, NAME VARCHAR(100), MANAGER_ID INT, INDEX (MANAGER_ID), FOREIGN KEY (MANAGER_ID) REFERENCES EMPLOYEES(ID) ); INSERT INTO EMPLOYEES VALUES (333, &amp;quot;Yasmina&amp;quot;, NULL), # Yasmina is the CEO (as her manager_id is NULL) (198, &amp;quot;John&amp;quot;, 333), # John is 198 and reports to 333 (=Yasmina) (692, &amp;quot;Tarek&amp;quot;, 333), (29, &amp;quot;Pedro&amp;quot;, 198), (4610, &amp;quot;Sarah&amp;quot;, 29), (72, &amp;quot;Pierre&amp;quot;, 29), (123, &amp;quot;Adil&amp;quot;, 692); # Give me the org chart with the management chain for every employee (= the path from CEO to employee): WITH RECURSIVE EMPLOYEES_EXTENDED (ID, NAME, PATH) AS ( SELECT ID, NAME, CAST(ID AS CHAR(200)) FROM EMPLOYEES WHERE MANAGER_ID IS NULL UNION ALL SELECT S.ID, S.NAME, CONCAT(M.PATH, &amp;quot;,&amp;quot;, S.ID) FROM EMPLOYEES_EXTENDED M JOIN EMPLOYEES S ON M.ID=S.MANAGER_ID ) SELECT * FROM EMPLOYEES_EXTENDED ORDER BY PATH; ID NAME PATH Yasmina 333 198 John 333,198 29 Pedro 333,198,29 4610 Sarah 333,198,29,4610 # Sarah-&amp;gt;Pedro-&amp;gt;John-&amp;gt;Yasmina 72 Pierre 333,198,29,72 692 Tarek 333,692 123 Adil 333,692,123 &amp;lt;numéro&amp;gt;
  35. CREATE TABLE EMPLOYEES ( ID INT PRIMARY KEY, NAME VARCHAR(100), MANAGER_ID INT, INDEX (MANAGER_ID), FOREIGN KEY (MANAGER_ID) REFERENCES EMPLOYEES(ID) ); INSERT INTO EMPLOYEES VALUES (333, &amp;quot;Yasmina&amp;quot;, NULL), # Yasmina is the CEO (as her manager_id is NULL) (198, &amp;quot;John&amp;quot;, 333), # John is 198 and reports to 333 (=Yasmina) (692, &amp;quot;Tarek&amp;quot;, 333), (29, &amp;quot;Pedro&amp;quot;, 198), (4610, &amp;quot;Sarah&amp;quot;, 29), (72, &amp;quot;Pierre&amp;quot;, 29), (123, &amp;quot;Adil&amp;quot;, 692); # Give me the org chart with the management chain for every employee (= the path from CEO to employee): WITH RECURSIVE EMPLOYEES_EXTENDED (ID, NAME, PATH) AS ( SELECT ID, NAME, CAST(ID AS CHAR(200)) FROM EMPLOYEES WHERE MANAGER_ID IS NULL UNION ALL SELECT S.ID, S.NAME, CONCAT(M.PATH, &amp;quot;,&amp;quot;, S.ID) FROM EMPLOYEES_EXTENDED M JOIN EMPLOYEES S ON M.ID=S.MANAGER_ID ) SELECT * FROM EMPLOYEES_EXTENDED ORDER BY PATH; ID NAME PATH Yasmina 333 198 John 333,198 29 Pedro 333,198,29 4610 Sarah 333,198,29,4610 # Sarah-&amp;gt;Pedro-&amp;gt;John-&amp;gt;Yasmina 72 Pierre 333,198,29,72 692 Tarek 333,692 123 Adil 333,692,123 &amp;lt;numéro&amp;gt;
  36. First rows defines the column types CREATE TABLE EMPLOYEES ( ID INT PRIMARY KEY, NAME VARCHAR(100), MANAGER_ID INT, INDEX (MANAGER_ID), FOREIGN KEY (MANAGER_ID) REFERENCES EMPLOYEES(ID) ); INSERT INTO EMPLOYEES VALUES (333, &amp;quot;Yasmina&amp;quot;, NULL), # Yasmina is the CEO (as her manager_id is NULL) (198, &amp;quot;John&amp;quot;, 333), # John is 198 and reports to 333 (=Yasmina) (692, &amp;quot;Tarek&amp;quot;, 333), (29, &amp;quot;Pedro&amp;quot;, 198), (4610, &amp;quot;Sarah&amp;quot;, 29), (72, &amp;quot;Pierre&amp;quot;, 29), (123, &amp;quot;Adil&amp;quot;, 692); # Give me the org chart with the management chain for every employee (= the path from CEO to employee): WITH RECURSIVE EMPLOYEES_EXTENDED (ID, NAME, PATH) AS ( SELECT ID, NAME, CAST(ID AS CHAR(200)) FROM EMPLOYEES WHERE MANAGER_ID IS NULL UNION ALL SELECT S.ID, S.NAME, CONCAT(M.PATH, &amp;quot;,&amp;quot;, S.ID) FROM EMPLOYEES_EXTENDED M JOIN EMPLOYEES S ON M.ID=S.MANAGER_ID ) SELECT * FROM EMPLOYEES_EXTENDED ORDER BY PATH; ID NAME PATH Yasmina 333 198 John 333,198 29 Pedro 333,198,29 4610 Sarah 333,198,29,4610 # Sarah-&amp;gt;Pedro-&amp;gt;John-&amp;gt;Yasmina 72 Pierre 333,198,29,72 692 Tarek 333,692 123 Adil 333,692,123 &amp;lt;numéro&amp;gt;
  37. Note: First row determines type CREATE TABLE EMPLOYEES ( ID INT PRIMARY KEY, NAME VARCHAR(100), MANAGER_ID INT, INDEX (MANAGER_ID), FOREIGN KEY (MANAGER_ID) REFERENCES EMPLOYEES(ID) ); INSERT INTO EMPLOYEES VALUES (333, &amp;quot;Yasmina&amp;quot;, NULL), # Yasmina is the CEO (as her manager_id is NULL) (198, &amp;quot;John&amp;quot;, 333), # John is 198 and reports to 333 (=Yasmina) (692, &amp;quot;Tarek&amp;quot;, 333), (29, &amp;quot;Pedro&amp;quot;, 198), (4610, &amp;quot;Sarah&amp;quot;, 29), (72, &amp;quot;Pierre&amp;quot;, 29), (123, &amp;quot;Adil&amp;quot;, 692); # Give me the org chart with the management chain for every employee (= the path from CEO to employee): WITH RECURSIVE EMPLOYEES_EXTENDED (ID, NAME, PATH) AS ( SELECT ID, NAME, CAST(ID AS CHAR(200)) FROM EMPLOYEES WHERE MANAGER_ID IS NULL UNION ALL SELECT S.ID, S.NAME, CONCAT(M.PATH, &amp;quot;,&amp;quot;, S.ID) FROM EMPLOYEES_EXTENDED M JOIN EMPLOYEES S ON M.ID=S.MANAGER_ID ) SELECT * FROM EMPLOYEES_EXTENDED ORDER BY PATH; ID NAME PATH Yasmina 333 198 John 333,198 29 Pedro 333,198,29 4610 Sarah 333,198,29,4610 # Sarah-&amp;gt;Pedro-&amp;gt;John-&amp;gt;Yasmina 72 Pierre 333,198,29,72 692 Tarek 333,692 123 Adil 333,692,123 &amp;lt;numéro&amp;gt;
  38. Note: First row determines type CREATE TABLE EMPLOYEES ( ID INT PRIMARY KEY, NAME VARCHAR(100), MANAGER_ID INT, INDEX (MANAGER_ID), FOREIGN KEY (MANAGER_ID) REFERENCES EMPLOYEES(ID) ); INSERT INTO EMPLOYEES VALUES (333, &amp;quot;Yasmina&amp;quot;, NULL), # Yasmina is the CEO (as her manager_id is NULL) (198, &amp;quot;John&amp;quot;, 333), # John is 198 and reports to 333 (=Yasmina) (692, &amp;quot;Tarek&amp;quot;, 333), (29, &amp;quot;Pedro&amp;quot;, 198), (4610, &amp;quot;Sarah&amp;quot;, 29), (72, &amp;quot;Pierre&amp;quot;, 29), (123, &amp;quot;Adil&amp;quot;, 692); # Give me the org chart with the management chain for every employee (= the path from CEO to employee): WITH RECURSIVE EMPLOYEES_EXTENDED (ID, NAME, PATH) AS ( SELECT ID, NAME, CAST(ID AS CHAR(200)) FROM EMPLOYEES WHERE MANAGER_ID IS NULL UNION ALL SELECT S.ID, S.NAME, CONCAT(M.PATH, &amp;quot;,&amp;quot;, S.ID) FROM EMPLOYEES_EXTENDED M JOIN EMPLOYEES S ON M.ID=S.MANAGER_ID ) SELECT * FROM EMPLOYEES_EXTENDED ORDER BY PATH; ID NAME PATH Yasmina 333 198 John 333,198 29 Pedro 333,198,29 4610 Sarah 333,198,29,4610 # Sarah-&amp;gt;Pedro-&amp;gt;John-&amp;gt;Yasmina 72 Pierre 333,198,29,72 692 Tarek 333,692 123 Adil 333,692,123 &amp;lt;numéro&amp;gt;
  39. DISTINCT is not included in the 8.0.0 labs release. Can be used to compute transitive closures when there are cycles since existing rows will not be added, and recursion will terminate when no more rows are added. &amp;lt;numéro&amp;gt;
  40. Note that this restriction is only for the recursive select, not the non-recursive/seed/anchor SELECT Of course, it can additionally reference other tables than the CTE and join them with the CTE. &amp;lt;numéro&amp;gt;
  41. Note that this restriction is only for the recursive select, not the non-recursive/seed/anchor SELECT Of course, it can additionally reference other tables than the CTE and join them with the CTE. &amp;lt;numéro&amp;gt;
  42. That concludes this presentation. For more information, check my blog, the optimizer team blog and the MySQL server team blog. There are also MySQL forums where you can ask questions related to Optimization of MySQL queries. We monitor these forums and will try to answer the question you may have. &amp;lt;numéro&amp;gt;
  43. This is a Safe Harbor Front slide, one of two Safe Harbor Statement slides included in this template. One of the Safe Harbor slides must be used if your presentation covers material affected by Oracle’s Revenue Recognition Policy To learn more about this policy, e-mail: Revrec-americasiebc_us@oracle.com For internal communication, Safe Harbor Statements are not required. However, there is an applicable disclaimer (Exhibit E) that should be used, found in the Oracle Revenue Recognition Policy for Future Product Communications. Copy and paste this link into a web browser, to find out more information.   http://my.oracle.com/site/fin/gfo/GlobalProcesses/cnt452504.pdf For all external communications such as press release, roadmaps, PowerPoint presentations, Safe Harbor Statements are required. You can refer to the link mentioned above to find out additional information/disclaimers required depending on your audience. &amp;lt;numéro&amp;gt;
  44. &amp;lt;numéro&amp;gt;