SlideShare une entreprise Scribd logo
1  sur  48
Télécharger pour lire hors ligne
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
Using Optimizer Hints to Improve
MySQL Query Performance
Øystein Grøvlen
Senior Principal Software Engineer
MySQL Optimizer Team, Oracle
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.
Copyright © 2017, Oracle and/or its affiliates. All rights reserved.
Program Agenda
Introduction to optimizer hints
Index hints
Join order hints
Subquery hints
Hints and query rewrite plugin
1
2
3
4
5
Copyright © 2017, Oracle and/or its affiliates. All rights reserved.
Program Agenda
Introduction to optimizer hints
Index hints
Join order hints
Subquery hints
Hints and query rewrite plugin
1
2
3
4
5
Copyright © 2017, Oracle and/or its affiliates. All rights reserved.
MySQL Optimizer
SELECT a, b
FROM t1, t2, t3
WHERE t1.a = t2.b
AND t2.b = t3.c
AND t2.d > 20
AND t2.d < 30;
MySQL Server
Cost based
optimizations
Heuristics
Cost Model
Optimizer
Table/index info
(data dictionary)
Statistics
(storage engines)
t2 t3
t1
Table
scan
Range
scan
Ref
access
JOIN
JOIN
Copyright © 2017, Oracle and/or its affiliates. All rights reserved.
Influencing the Optimizer with Hints
• Limit which indexes may be used:
– USE INDEX, FORCE INDEX, IGNORE INDEX
• Force specific join order:
– STRAIGHT_JOIN
• New optimizer hints (MySQL 5.7)
– Syntax:
SELECT /*+ HINT1(args) HINT2(args) */ … FROM …
– May be used for SELECT/UPDATE/INSERT/DELETE statements
– May also be used in sub-queries
When the optimizer does not pick the best query plan
Copyright © 2017, Oracle and/or its affiliates. All rights reserved.
New Optimizer Hints
• Hints in 5.7:
– BKA(tables)/NO_BKA(tables), BNL(tables)/NO_BNL(tables)
– MRR(table indexes)/NO_MRR(table indexes)
– SEMIJOIN/NO_SEMIJOIN(strategies), SUBQUERY(strategy)
– NO_ICP(table indexes)
– NO_RANGE_OPTIMIZATION(table indexes)
– QB_NAME(name)
• Hints in 8.0.0 Optimizer Labs Release
– MERGE(views)/NO_MERGE(views)
– JOIN_ORDER(tables) JOIN_PREFIX(tables) JOIN_SUFFIX(tables) JOIN_FIXED_ORDER()
Copyright © 2017, Oracle and/or its affiliates. All rights reserved.
Optimizer Hints
• Comment syntax:
– Portable: Will not fail if server does not support optimizer hint
• Warnings on
– Syntax errors in hint
– Symbols not found
– Hint conflicts
• If conflicting hints, first hint will be accepted
• EXPLAIN warning shows which hint was accepted
– Note: No warning if hint is accepted, but is not applicable
Warnings not errors
Copyright © 2017, Oracle and/or its affiliates. All rights reserved.
Optimizer Hints
mysql> EXPLAIN SELECT /*+ MRR(orders) */ SUM(o_totalprice) FROM orders WHERE o_orderdate
BETWEEN '1994-06-17' AND '1994-06-22';
+----+-------------+--------+------------+-------+---------------+---------------+---------+------+---
----+----------+----------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref |
rows | filtered | Extra |
+----+-------------+--------+------------+-------+---------------+---------------+---------+------+---
----+----------+----------------------------------+
| 1 | SIMPLE | orders | NULL | range | i_o_orderdate | i_o_orderdate | 4 | NULL |
68584 | 100.00 | Using index condition; Using MRR |
+----+-------------+--------+------------+-------+---------------+---------------+---------+------+---
----+----------+----------------------------------+
1 row in set, 1 warning (0,01 sec)
Note (Code 1003): /* select#1 */ select /*+ MRR(`orders`@`select#1`) */
sum(`dbt3`.`orders`.`o_totalprice`) AS `sum(o_totalprice)` from `dbt3`.`orders` where
(`dbt3`.`orders`.`o_orderDATE` between '1994-06-17' and '1994-06-22')
Example
Copyright © 2017, Oracle and/or its affiliates. All rights reserved.
Optimizer Hints
mysql> EXPLAIN SELECT /*+ MRR(orders) NO_ICP(orders i_o_orderdate) */ SUM(o_totalprice)
FROM orders WHERE o_orderdate BETWEEN '1994-06-17' AND '1994-06-22';
+----+-------------+--------+------------+-------+---------------+---------------+---------+------+---
----+----------+----------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref |
rows | filtered | Extra |
+----+-------------+--------+------------+-------+---------------+---------------+---------+------+---
----+----------+----------------------------------+
| 1 | SIMPLE | orders | NULL | range | i_o_orderdate | i_o_orderdate | 4 | NULL |
68584 | 100.00 | Using where; Using MRR |
+----+-------------+--------+------------+-------+---------------+---------------+---------+------+---
----+----------+----------------------------------+
1 row in set, 1 warning (0,01 sec)
Note (Code 1003): /* select#1 */ select /*+ MRR(`orders`@`select#1`) NO_ICP(`orders`@`select#1`
`i_o_orderdate`) */ sum(`dbt3`.`orders`.`o_totalprice`) AS `sum(o_totalprice)` from `dbt3`.`orders`
where (`dbt3`.`orders`.`o_orderDATE` between '1994-06-17' and '1994-06-22')
Example: Multiple hints
Copyright © 2017, Oracle and/or its affiliates. All rights reserved.
Optimizer Hints
mysql> EXPLAIN SELECT /*+ MRR(t1) */ SUM(o_totalprice) FROM orders WHERE o_orderdate
BETWEEN '1994-06-17' AND '1994-06-22';
+----+-------------+--------+------------+-------+---------------+---------------+---------+------+---
----+----------+----------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref |
rows | filtered | Extra |
+----+-------------+--------+------------+-------+---------------+---------------+---------+------+---
----+----------+----------------------------------+
| 1 | SIMPLE | orders | NULL | range | i_o_orderdate | i_o_orderdate | 4 | NULL |
68584 | 100.00 | Using index condition |
+----+-------------+--------+------------+-------+---------------+---------------+---------+------+---
----+----------+----------------------------------+
1 row in set, 1 warning (0,01 sec)
Warning (Code 3128): Unresolved name `t1`@`select#1` for MRR hint
Note (Code 1003): /* select#1 */ select sum(`dbt3`.`orders`.`o_totalprice`) AS `sum(o_totalprice)`
from `dbt3`.`orders` where (`dbt3`.`orders`.`o_orderDATE` between '1994-06-17' and '1994-06-22')
Example: Unresolved names
Copyright © 2017, Oracle and/or its affiliates. All rights reserved.
Optimizer Hints
mysql> EXPLAIN SELECT /*+ MRR(orders) NO_MRR(orders) */ SUM(o_totalprice) FROM orders
WHERE o_orderdate BETWEEN '1994-06-17' AND '1994-06-22';
+----+-------------+--------+------------+-------+---------------+---------------+---------+------+---
----+----------+----------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref |
rows | filtered | Extra |
+----+-------------+--------+------------+-------+---------------+---------------+---------+------+---
----+----------+----------------------------------+
| 1 | SIMPLE | orders | NULL | range | i_o_orderdate | i_o_orderdate | 4 | NULL |
68584 | 100.00 | Using index condition; Using MRR |
+----+-------------+--------+------------+-------+---------------+---------------+---------+------+---
----+----------+----------------------------------+
1 row in set, 1 warning (0,01 sec)
Warning (Code 3126): Hint NO_MRR(`orders` ) is ignored as conflicting/duplicated
Note (Code 1003): /* select#1 */ select /*+ MRR(`orders`@`select#1`) */
sum(`dbt3`.`orders`.`o_totalprice`) AS `sum(o_totalprice)` from `dbt3`.`orders` where
(`dbt3`.`orders`.`o_orderDATE` between '1994-06-17' and '1994-06-22')
Example: Conflicting hints
Copyright © 2017, Oracle and/or its affiliates. All rights reserved.
Optimizer Hints
mysql> EXPLAIN SELECT /*+ MRR(orders) */ SUM(o_totalprice) FROM orders WHERE o_orderdate
= '1994-06-17';
+----+-------------+--------+------------+------+---------------+---------------+---------+-------+---
---+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref |
rows | filtered | Extra |
+----+-------------+--------+------------+------+---------------+---------------+---------+-------+---
---+----------+-------+
| 1 | SIMPLE | orders | NULL | ref | i_o_orderdate | i_o_orderdate | 4 | const |
6440 | 100.00 | NULL |
+----+-------------+--------+------------+------+---------------+---------------+---------+-------+---
---+----------+-------+
1 row in set, 1 warning (0,00 sec)
Note (Code 1003): /* select#1 */ select /*+ MRR(`orders`@`select#1`) */
sum(`dbt3`.`orders`.`o_totalprice`) AS `sum(o_totalprice)` from `dbt3`.`orders` where
(`dbt3`.`orders`.`o_orderDATE` = '1994-06-17')
Example: Hint not applicable
Copyright © 2017, Oracle and/or its affiliates. All rights reserved.
Optimizer Hints
• Hints we consider to add
– Force/ignore index_merge alternatives
– Reimplement index hints in new syntax
– Hints within views
– Temporarily set session variables for just one query
Future plans
Copyright © 2017, Oracle and/or its affiliates. All rights reserved.
Program Agenda
Introduction to optimizer hints
Index hints
Join order hints
Subquery hints
Hints and query rewrite plugin
1
2
3
4
5
Copyright © 2017, Oracle and/or its affiliates. All rights reserved.
Index hints
• USE INDEX (index_list)
– Restrict which indexes are considered
– Table scan may be used
• FORCE INDEX(index_list)
– Use one of the specified indexes
– Table scan may only be used if none of the indexes are applicable
• IGNORE INDEX(index_list)
– Do not use the specified index
• Follows table name in FROM clause
... FROM t1 IGNORE INDEX(idx1) ...
Confidential – Oracle Internal/Restricted/Highly Restricted 15
Copyright © 2017, Oracle and/or its affiliates. All rights reserved.
Index Hints
Table scan:
• IO-cost: #pages in table * IO_BLOCK_READ_COST
• CPU cost: #rows * ROW_EVALUATE_COST
Range scan (on secondary index):
• IO-cost: #rows_in_range * IO_BLOCK_READ_COST
• CPU cost: #rows_in_range * ROW_EVALUATE_COST
Example
SELECT SUM(o_totalprice) FROM orders
WHERE o_orderdate BETWEEN '1994-01-01' AND '1994-12-31';
Copyright © 2017, Oracle and/or its affiliates. All rights reserved.
Table Scan or Index Range Scan?
EXPLAIN SELECT SUM(o_totalprice) FROM orders
WHERE o_orderdate BETWEEN '1994-01-01' AND '1994-12-31';
EXPLAIN SELECT SUM(o_totalprice) FROM orders
WHERE o_orderdate BETWEEN '1994-01-01' AND '1994-06-30';
id
select
type
table type possible keys key
key
len
ref rows extra
1 SIMPLE orders ALL i_o_orderdate NULL NULL NULL 15000000 Using where
Id
select
type
table type possible keys key
key
len
ref rows extra
1 SIMPLE orders range i_o_orderdate i_o_orderdate 4 NULL 2235118
Using index
condition
Copyright © 2017, Oracle and/or its affiliates. All rights reserved.
Cost Model vs Real World
Data in Memory Data on Disk Data on SSD
Table scan 6.8 seconds 36 seconds 15 seconds
Index scan 5.2 seconds 2.5 hours 30 minutes
Measured Execution Times
Force Index Scan with a hint:
SELECT SUM(o_totalprice)
FROM orders FORCE INDEX (i_o_orderdate)
WHERE o_orderdate BETWEEN '1994-01-01' AND '1994-12-31';
Copyright © 2017, Oracle and/or its affiliates. All rights reserved.
Index Merge Intersection
• Combine several indexes to reduce number of (or avoid) accesses to base
table for ANDed conditions
• Example:
SELECT * FROM t1 WHERE a=10 AND b=10
• Index Merge Intersection:
10INDEX(a)
10INDEX(b)
a=10 AND b=10Result:
Intersection
Copyright © 2017, Oracle and/or its affiliates. All rights reserved.
Index Merge Intersection
SELECT count(*) FROM user
WHERE user_type=2 AND status=1 AND parent_id=0;
Beware of low-selectivity indexes!
id
select
type
table type
possible
keys
key
key
len
ref rows Extra
1 SIMPLE user
index_
merge
parent_id,
status,
user_type
user_type,
status,
parent_id
1,1,4 NULL 3696
Using intersect (user_type,
status, parent_id);
Using where; Using index
mysql> SELECT count(*) FROM user WHERE user_type=2 AND status=1 …
...
1 row in set (5.33 sec)
mysql> SELECT count(*) FROM user USE INDEX (user_type) WHERE user_type=2 …
...
1 row in set (0.09 sec)
Low selectivity
Source: http://www.mysqlperformanceblog.com/2012/12/14/
the-optimization-that-often-isnt-index-merge-intersection/
Copyright © 2017, Oracle and/or its affiliates. All rights reserved.
Index Merge Intersection
mysql> FLUSH STATUS;
mysql> SELECT count(*) FROM user
WHERE user_type=2 AND status=1
AND parent_id=0;
...
1 row in set (5.28 sec)
mysql> SHOW STATUS LIKE 'Handler_read%';
+-----------------------+----------+
| Variable_name | Value |
+-----------------------+----------+
| Handler_read_first | 0 |
| Handler_read_key | 3 |
| Handler_read_last | 0 |
| Handler_read_next | 15825904 |
| Handler_read_prev | 0 |
| Handler_read_rnd | 0 |
| Handler_read_rnd_next | 0 |
+-----------------------+----------+
Handler status variables
mysql> FLUSH STATUS;
mysql> SELECT count(*) FROM user
USE INDEX (user_id) WHERE user_type=2 AND
status=1 AND parent_id=0;
...
1 row in set (0.09 sec)
mysql> SHOW STATUS LIKE 'Handler_read%‘;
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| Handler_read_first | 0 |
| Handler_read_key | 1 |
| Handler_read_last | 0 |
| Handler_read_next | 23312 |
| Handler_read_prev | 0 |
| Handler_read_rnd | 0 |
| Handler_read_rnd_next | 0 |
+-----------------------+-------+
Copyright © 2017, Oracle and/or its affiliates. All rights reserved.
Program Agenda
Introduction to optimizer hints
Index hints
Join order hints
Subquery hints
Hints and query rewrite plugin
1
2
3
4
5
Copyright © 2017, Oracle and/or its affiliates. All rights reserved.
Join order hints
• Specify complete join order
SELECT STRAIGHT_JOIN ... FROM t1 JOIN t2 JOIN t3 ...
• Specify order of two tables
SELECT ... FROM t1 STRAIGHT_JOIN t2 JOIN t3 ...
• New join order hints in MySQL 8.0
– Full order: SELECT /*+ JOIN_FIXED_ORDER() */ ... FROM t1 JOIN t2 JOIN t3 ...
– Partial order: SELECT /*+ JOIN_ORDER(t1, t2) */ ... FROM t1 JOIN t2 JOIN t3 ...
– First tables: SELECT /*+ JOIN_PREFIX(t1) */ ... FROM t1 JOIN t2 JOIN t3 ...
– Last tables: SELECT /*+ JOIN_SUFFIX(t1) */ ... FROM t1 JOIN t2 JOIN t3 ...
– Confidential – Oracle Internal/Restricted/Highly Restricted 23
Copyright © 2017, Oracle and/or its affiliates. All rights reserved.
Join Optimizer
Example
EXPLAIN SELECT *
FROM orders JOIN customer ON o_custkey = c_custkey
WHERE o_orderdate < '1993-01-01' AND c_acctbal < -1000;
id
select
type
table type possible keys key
key
len
ref rows filtered Extra
1 SIMPLE orders ALL
i_o_orderdate,
i_o_custkey
NULL NULL NULL 15000000 31.19
Using
where
1 SIMPLE customer
eq_
ref
PRIMARY PRIMARY 4
dbt3.orders.
o_custkey
1 33.33
Using
where
Copyright © 2017, Oracle and/or its affiliates. All rights reserved.
Join Optimizer
Change join order with a hint
EXPLAIN SELECT /*+ JOIN_PREFIX(customer) */ *
FROM orders JOIN customer ON o_custkey = c_custkey
WHERE o_orderdate < '1993-01-01' AND c_acctbal < -1000;
id
select
type
table type possible keys key
key
len
ref rows filtered extra
1 SIMPLE customer ALL PRIMARY NULL NULL NULL 1500000 33.33
Using
where
1 SIMPLE Orders ref
i_o_orderdate,
i_o_custkey
PRIM
ARY
4
dbt3.orders.
o_custkey
1 33.33
Using
where
id
select
type
table type possible keys key
key
len
ref rows filtered Extra
1 SIMPLE customer ALL PRIMARY NULL NULL NULL 1500000 33.33
Using
where
1 SIMPLE orders ref
i_o_orderdate,
i_o_custkey
i_o_custkey 5
dbt3.
customer.
c_custkey
15 31.19
Using
where
Alternative hints with same effect:
JOIN_ORDER(customer, orders) JOIN_SUFFIX(orders)
Copyright © 2017, Oracle and/or its affiliates. All rights reserved.
Join Order
0
2
4
6
8
10
12
14
16
QueryExecutionTime(seconds)
orders → customer customer → orders
Performance
Copyright © 2017, Oracle and/or its affiliates. All rights reserved.
DBT-3 Query 8
SELECT o_year, SUM(CASE WHEN nation = 'FRANCE' THEN volume ELSE 0 END) / SUM(volume) AS
mkt_share
FROM (
SELECT EXTRACT(YEAR FROM o_orderdate) AS o_year,
l_extendedprice * (1 - l_discount) AS volume, n2.n_name AS nation
FROM part
JOIN lineitem ON p_partkey = l_partkey
JOIN supplier ON s_suppkey = l_suppkey
JOIN orders ON l_orderkey = o_orderkey
JOIN customer ON o_custkey = c_custkey
JOIN nation n1 ON c_nationkey = n1.n_nationkey
JOIN region ON n1.n_regionkey = r_regionkey
JOIN nation n2 ON s_nationkey = n2.n_nationkey
WHERE r_name = 'EUROPE' AND o_orderdate BETWEEN '1995-01-01' AND '1996-12-31'
AND p_type = 'PROMO BRUSHED STEEL'
) AS all_nations GROUP BY o_year ORDER BY o_year;
National Market Share Query
Copyright © 2017, Oracle and/or its affiliates. All rights reserved.
DBT-3 Query 8
MySQL Workbench: Visual EXPLAIN (MySQL 5.6)
Execution time: 21 seconds
Copyright © 2017, Oracle and/or its affiliates. All rights reserved.
DBT-3 Query 8
SELECT o_year, SUM(CASE WHEN nation = 'FRANCE' THEN volume ELSE 0 END) / SUM(volume) AS
mkt_share
FROM (
SELECT EXTRACT(YEAR FROM o_orderdate) AS o_year,
l_extendedprice * (1 - l_discount) AS volume, n2.n_name AS nation
FROM part
STRAIGHT_JOIN lineitem ON p_partkey = l_partkey
JOIN supplier ON s_suppkey = l_suppkey
JOIN orders ON l_orderkey = o_orderkey
JOIN customer ON o_custkey = c_custkey
JOIN nation n1 ON c_nationkey = n1.n_nationkey
JOIN region ON n1.n_regionkey = r_regionkey
JOIN nation n2 ON s_nationkey = n2.n_nationkey
WHERE r_name = 'EUROPE' AND o_orderdate BETWEEN '1995-01-01' AND '1996-12-31'
AND p_type = 'PROMO BRUSHED STEEL'
) AS all_nations GROUP BY o_year ORDER BY o_year;
Force early processing of high selectivity conditions
Highest selectivity
part before lineitem
Copyright © 2017, Oracle and/or its affiliates. All rights reserved.
DBT-3 Query 8
Improved join order
Execution time: 3 seconds
Copyright © 2017, Oracle and/or its affiliates. All rights reserved.
MySQL 5.7: Improved join order
Improvements to Query 8 in MySQL 5.7:
• Filtering on non-indexed columns are taken into account
– No need for hint to force part table to be processed early
• Merge derived tables into outer query
– No temporary table
Copyright © 2017, Oracle and/or its affiliates. All rights reserved.
Program Agenda
Introduction to optimizer hints
Index hints
Join order hints
Subquery hints
Hints and query rewrite plugin
1
2
3
4
5
Copyright © 2017, Oracle and/or its affiliates. All rights reserved.
Subquery category:
• IN (SELECT …)
• NOT IN (SELECT …)
• FROM (SELECT …)
• <CompOp> ALL/ANY (SELECT ..)
• EXISTS/other
Strategy:
Overview of Subquery Optimizations
• Semi-join
• Materialization
• IN ➜ EXISTS
• Merged
• Materialized
• MAX/MIN re-write
• Execute subquery
New in
MySQL 5.7
Copyright © 2017, Oracle and/or its affiliates. All rights reserved.
Derived Tables
• Subquery in FROM clause
SELECT AVG(o_totalprice) FROM
( SELECT * FROM orders ORDER BY o_totalprice DESC LIMIT 100000 ) td;
• MySQL 5.6 and earlier: Executed separately and result stored in a
temporary table (materialization)
• MySQL 5.6 and later: If useful, index will be created on the temporary table
• MySQL 5.7: Treat derived tables like views: May be merged with outer
query block
Copyright © 2017, Oracle and/or its affiliates. All rights reserved.
Derived Tables
SELECT * FROM part p1 JOIN
(SELECT * FROM part WHERE p_type LIKE '%STEEL%') p2 ON p1.p_name = p2.p_name
WHERE p1.p_type LIKE '%COPPER%';
Example
MySQL 5.5 MySQL 5.6 MySQL 5.7
0.4 seconds 6 minutes
Copyright © 2017, Oracle and/or its affiliates. All rights reserved.
Hint: Merge/Materialize Derived Table or View
• Derived tables/views are, if possible, merged into outer query
• NO_MERGE hint can be used to override default behavior:
SELECT /*+ NO_MERGE(dt) */ *
FROM t1 JOIN (SELECT x, y FROM t2) dt ON t1.x = dt.x;
• MERGE hint will force a merge
SELECT /*+ MERGE(dt) */ *
FROM t1 JOIN (SELECT x, y FROM t2) dt ON t1.x = dt.x;
• Can also use MERGE/NO_MERGE hints for views
SELECT /*+ NO_MERGE(v) */ * FROM t1 JOIN v ON t1.x = v.x;
Confidential – Oracle Internal/Restricted/Highly Restricted 36
MySQL 8.0.0 optimizer labs release
Copyright © 2017, Oracle and/or its affiliates. All rights reserved.
Derived Tables
SELECT /*+ NO_MERGE(p2) */ * FROM part p1 JOIN
(SELECT * FROM part WHERE p_type LIKE '%STEEL%') p2 ON p1.p_name = p2.p_name
WHERE p1.p_type LIKE '%COPPER%';
NO_MERGE hint
id
select
type
table type
possible
keys
key key len ref rows Extra
1 PRIMARY p1 ALL NULL NULL NULL NULL 200000 Using where
1 PRIMARY <derived2> ref <auto_key0> <auto_key0> 58 dbt3.p1.p_name 10 NULL
2 DERIVED part ALL NULL NULL NULL NULL 200000 Using where
Copyright © 2017, Oracle and/or its affiliates. All rights reserved.
Semi-join
• Convert IN - subquery to inner join, BUT
– Need some way to remove duplicates
• Different strategies for duplicate removal:
– FirstMatch (equivalent to IN→EXISTS execution)
– LooseScan (index scan, skip duplicates)
– Materialization: MatLookup (like subquery materialization), MatScan (materialized
table is first in join order)
– Duplicate WeedOut (insert result rows of semi-join query into temporary table with
unique index; duplicate rows will be rejected. Any join order.)
• If duplicate removal is not necessary:
– Table pull-out
Copyright © 2017, Oracle and/or its affiliates. All rights reserved.
• Disable semi-join with hint:
EXPLAIN SELECT * FROM t2 WHERE t2.a IN (SELECT /*+ NO_SEMIJOIN() */ a FROM t3);
• No hint, optimizer chooses semi-join algorithm LooseScan:
EXPLAIN SELECT * FROM t2 WHERE t2.a IN (SELECT a FROM t3);
MySQL 5.7: Hint Example: SEMIJOIN
id select type table type
possible
keys
key
key
len
ref rows Extra
1 SIMPLE t3 index a a 4 NULL 3 Using where; LooseScan
1 SIMPLE t2 ref a a 4 test.t3.a 1 Using index
id select type table type
possible
keys
key
key
len
ref rows Extra
1 PRIMARY t2 index null a 4 NULL 4 Using where; Using index
2 DEPENDENT
SUBQUERY
t3 Index_
subquery
a a 4 func 1 Using index
Copyright © 2017, Oracle and/or its affiliates. All rights reserved.
MySQL 5.7: Hint Example: SEMIJOIN
• Force Semi-join Materialization to be used
EXPLAIN SELECT /*+ SEMIJOIN(@subq MATERIALIZATION) */ * FROM t2
WHERE t2.a IN (SELECT /*+ QB_NAME(subq) */ a FROM t3);
3 rows in set, 1 warning (0.01 sec)
id select type table type
possible
keys
key
key
len
ref rows Extra
1 SIMPLE t2 index a a 4 NULL 4 Using where;
Using index
1 SIMPLE <subquery2> eq_ref <auto_key> <auto_key> 4 test.t2.a 1 NULL
2 MATERIALIZED t3 index a a 4 NULL 3 Using index
Copyright © 2017, Oracle and/or its affiliates. All rights reserved.
SELECT l_orderkey
FROM lineitem
GROUP BY l_orderkey
HAVING SUM(l_quantity) > 313
SELECT o_orderdate, o_totalprice
FROM orders
WHERE o_orderkey IN (
);
Subquery Materialization
1. Execute subquery once and store result in a temporary table
– Table has unique index for quick look-up and duplicate removal.
2. Execute outer query and check for matches in temporary table.
Materialize
Copyright © 2017, Oracle and/or its affiliates. All rights reserved.
Subquery Materialization
SELECT o_orderdate, o_totalprice FROM orders WHERE o_orderkey IN (
SELECT l_orderkey FROM lineitem GROUP BY l_orderkey HAVING SUM(l_quantity) > 313);
SELECT o_orderdate, o_totalprice FROM orders WHERE o_orderkey IN (SELECT /*+ SUBQUERY(INTOEXISTS)*/
l_orderkey FROM lineitem GROUP BY l_orderkey HAVING SUM(l_quantity) > 313);
id select type table type possible keys key
key
len
ref rows Extra
1 PRIMARY orders ALL NULL NULL NULL NULL 1500000 Using where
2 SUBQUERY lineitem index PRIMARY, ... PRIMARY 8 NULL 6001215 NULL
id select type table type possible keys key
key
len
ref rows Extra
1 PRIMARY orders ALL NULL NULL NULL NULL 1500000 Using where
2
DEPENDENT
SUBQUERY
lineitem index PRIMARY, ... PRIMARY 8 NULL 6001215 NULL
Copyright © 2017, Oracle and/or its affiliates. All rights reserved.
35,6
0,110 0,126 0,113
8,59
64,0
0
10
20
30
40
50
60
70
QueryExecutionTime(seconds)
FirstMatch LooseScan DupsWeedout MatScan Subquery Mat. InToExists
SELECT o_totalprice
FROM orders
WHERE o_orderkey IN
(SELECT l_orderkey
FROM lineitem
WHERE l_shipdate =
'1996-09-30');
DBT-3, Scale 10 (23 GB)
innodb_buffer_pool_size= 32 GB
(CPU-bound)
MySQL 5.6: Semi-join: Example
Copyright © 2017, Oracle and/or its affiliates. All rights reserved.
Program Agenda
Introduction to optimizer hints
Index hints
Join order hints
Subquery hints
Hints and query rewrite plugin
1
2
3
4
5
Copyright © 2017, Oracle and/or its affiliates. All rights reserved.
MySQL 5.7: Query Rewrite Plugin
• Rewrite problematic queries without the need to make application changes
– Add hints
– Modify join order
– Much more …
• Add rewrite rules to table:
INSERT INTO query_rewrite.rewrite_rules (pattern, replacement ) VALUES
("SELECT * FROM t1 WHERE a > ? AND b = ?",
"SELECT * FROM t1 FORCE INDEX (a_idx) WHERE a > ? AND b = ?");
• New pre- and post-parse query rewrite APIs
– Users can write their own plug-ins
Copyright © 2017, Oracle and/or its affiliates. All rights reserved.
More information
• MySQL Server Team blog
– http://mysqlserverteam.com/
• My blog:
– http://oysteing.blogspot.com/
• Optimizer team blog:
– http://mysqloptimizerteam.blogspot.com/
• MySQL forums:
– Optimizer & Parser: http://forums.mysql.com/list.php?115
– Performance: http://forums.mysql.com/list.php?24
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.
47
Using Optimizer Hints to Improve MySQL Query Performance

Contenu connexe

Tendances

MySQL Query And Index Tuning
MySQL Query And Index TuningMySQL Query And Index Tuning
MySQL Query And Index TuningManikanda kumar
 
MySQL 8.0 Optimizer Guide
MySQL 8.0 Optimizer GuideMySQL 8.0 Optimizer Guide
MySQL 8.0 Optimizer GuideMorgan Tocker
 
MySQL Performance Tuning: Top 10 Tips
MySQL Performance Tuning: Top 10 TipsMySQL Performance Tuning: Top 10 Tips
MySQL Performance Tuning: Top 10 TipsOSSCube
 
How to Analyze and Tune MySQL Queries for Better Performance
How to Analyze and Tune MySQL Queries for Better PerformanceHow to Analyze and Tune MySQL Queries for Better Performance
How to Analyze and Tune MySQL Queries for Better Performanceoysteing
 
Oracle statistics by example
Oracle statistics by exampleOracle statistics by example
Oracle statistics by exampleMauro Pagano
 
Redo log improvements MYSQL 8.0
Redo log improvements MYSQL 8.0Redo log improvements MYSQL 8.0
Redo log improvements MYSQL 8.0Mydbops
 
How to Take Advantage of Optimizer Improvements in MySQL 8.0
How to Take Advantage of Optimizer Improvements in MySQL 8.0How to Take Advantage of Optimizer Improvements in MySQL 8.0
How to Take Advantage of Optimizer Improvements in MySQL 8.0Norvald Ryeng
 
MySQL Performance Schema in Action: the Complete Tutorial
MySQL Performance Schema in Action: the Complete TutorialMySQL Performance Schema in Action: the Complete Tutorial
MySQL Performance Schema in Action: the Complete TutorialSveta Smirnova
 
Query Optimization with MySQL 5.7 and MariaDB 10: Even newer tricks
Query Optimization with MySQL 5.7 and MariaDB 10: Even newer tricksQuery Optimization with MySQL 5.7 and MariaDB 10: Even newer tricks
Query Optimization with MySQL 5.7 and MariaDB 10: Even newer tricksJaime Crespo
 
ProxySQL and the Tricks Up Its Sleeve - Percona Live 2022.pdf
ProxySQL and the Tricks Up Its Sleeve - Percona Live 2022.pdfProxySQL and the Tricks Up Its Sleeve - Percona Live 2022.pdf
ProxySQL and the Tricks Up Its Sleeve - Percona Live 2022.pdfJesmar Cannao'
 
MySQL8.0_performance_schema.pptx
MySQL8.0_performance_schema.pptxMySQL8.0_performance_schema.pptx
MySQL8.0_performance_schema.pptxNeoClova
 
Query Optimization with MySQL 5.6: Old and New Tricks - Percona Live London 2013
Query Optimization with MySQL 5.6: Old and New Tricks - Percona Live London 2013Query Optimization with MySQL 5.6: Old and New Tricks - Percona Live London 2013
Query Optimization with MySQL 5.6: Old and New Tricks - Percona Live London 2013Jaime Crespo
 
Modern query optimisation features in MySQL 8.
Modern query optimisation features in MySQL 8.Modern query optimisation features in MySQL 8.
Modern query optimisation features in MySQL 8.Mydbops
 
MySQL Advanced Administrator 2021 - 네오클로바
MySQL Advanced Administrator 2021 - 네오클로바MySQL Advanced Administrator 2021 - 네오클로바
MySQL Advanced Administrator 2021 - 네오클로바NeoClova
 
Histogram-in-Parallel-universe-of-MySQL-and-MariaDB
Histogram-in-Parallel-universe-of-MySQL-and-MariaDBHistogram-in-Parallel-universe-of-MySQL-and-MariaDB
Histogram-in-Parallel-universe-of-MySQL-and-MariaDBMydbops
 
MySql Practical Partitioning
MySql Practical PartitioningMySql Practical Partitioning
MySql Practical PartitioningAndrei Tsibets
 
MySQL Administrator 2021 - 네오클로바
MySQL Administrator 2021 - 네오클로바MySQL Administrator 2021 - 네오클로바
MySQL Administrator 2021 - 네오클로바NeoClova
 
InnoDB MVCC Architecture (by 권건우)
InnoDB MVCC Architecture (by 권건우)InnoDB MVCC Architecture (by 권건우)
InnoDB MVCC Architecture (by 권건우)I Goo Lee.
 
Dd and atomic ddl pl17 dublin
Dd and atomic ddl pl17 dublinDd and atomic ddl pl17 dublin
Dd and atomic ddl pl17 dublinStåle Deraas
 

Tendances (20)

MySQL Query And Index Tuning
MySQL Query And Index TuningMySQL Query And Index Tuning
MySQL Query And Index Tuning
 
MySQL 8.0 Optimizer Guide
MySQL 8.0 Optimizer GuideMySQL 8.0 Optimizer Guide
MySQL 8.0 Optimizer Guide
 
MySQL Performance Tuning: Top 10 Tips
MySQL Performance Tuning: Top 10 TipsMySQL Performance Tuning: Top 10 Tips
MySQL Performance Tuning: Top 10 Tips
 
How to Analyze and Tune MySQL Queries for Better Performance
How to Analyze and Tune MySQL Queries for Better PerformanceHow to Analyze and Tune MySQL Queries for Better Performance
How to Analyze and Tune MySQL Queries for Better Performance
 
Oracle statistics by example
Oracle statistics by exampleOracle statistics by example
Oracle statistics by example
 
Redo log improvements MYSQL 8.0
Redo log improvements MYSQL 8.0Redo log improvements MYSQL 8.0
Redo log improvements MYSQL 8.0
 
MySQL Shell for DBAs
MySQL Shell for DBAsMySQL Shell for DBAs
MySQL Shell for DBAs
 
How to Take Advantage of Optimizer Improvements in MySQL 8.0
How to Take Advantage of Optimizer Improvements in MySQL 8.0How to Take Advantage of Optimizer Improvements in MySQL 8.0
How to Take Advantage of Optimizer Improvements in MySQL 8.0
 
MySQL Performance Schema in Action: the Complete Tutorial
MySQL Performance Schema in Action: the Complete TutorialMySQL Performance Schema in Action: the Complete Tutorial
MySQL Performance Schema in Action: the Complete Tutorial
 
Query Optimization with MySQL 5.7 and MariaDB 10: Even newer tricks
Query Optimization with MySQL 5.7 and MariaDB 10: Even newer tricksQuery Optimization with MySQL 5.7 and MariaDB 10: Even newer tricks
Query Optimization with MySQL 5.7 and MariaDB 10: Even newer tricks
 
ProxySQL and the Tricks Up Its Sleeve - Percona Live 2022.pdf
ProxySQL and the Tricks Up Its Sleeve - Percona Live 2022.pdfProxySQL and the Tricks Up Its Sleeve - Percona Live 2022.pdf
ProxySQL and the Tricks Up Its Sleeve - Percona Live 2022.pdf
 
MySQL8.0_performance_schema.pptx
MySQL8.0_performance_schema.pptxMySQL8.0_performance_schema.pptx
MySQL8.0_performance_schema.pptx
 
Query Optimization with MySQL 5.6: Old and New Tricks - Percona Live London 2013
Query Optimization with MySQL 5.6: Old and New Tricks - Percona Live London 2013Query Optimization with MySQL 5.6: Old and New Tricks - Percona Live London 2013
Query Optimization with MySQL 5.6: Old and New Tricks - Percona Live London 2013
 
Modern query optimisation features in MySQL 8.
Modern query optimisation features in MySQL 8.Modern query optimisation features in MySQL 8.
Modern query optimisation features in MySQL 8.
 
MySQL Advanced Administrator 2021 - 네오클로바
MySQL Advanced Administrator 2021 - 네오클로바MySQL Advanced Administrator 2021 - 네오클로바
MySQL Advanced Administrator 2021 - 네오클로바
 
Histogram-in-Parallel-universe-of-MySQL-and-MariaDB
Histogram-in-Parallel-universe-of-MySQL-and-MariaDBHistogram-in-Parallel-universe-of-MySQL-and-MariaDB
Histogram-in-Parallel-universe-of-MySQL-and-MariaDB
 
MySql Practical Partitioning
MySql Practical PartitioningMySql Practical Partitioning
MySql Practical Partitioning
 
MySQL Administrator 2021 - 네오클로바
MySQL Administrator 2021 - 네오클로바MySQL Administrator 2021 - 네오클로바
MySQL Administrator 2021 - 네오클로바
 
InnoDB MVCC Architecture (by 권건우)
InnoDB MVCC Architecture (by 권건우)InnoDB MVCC Architecture (by 권건우)
InnoDB MVCC Architecture (by 권건우)
 
Dd and atomic ddl pl17 dublin
Dd and atomic ddl pl17 dublinDd and atomic ddl pl17 dublin
Dd and atomic ddl pl17 dublin
 

En vedette

MySQL 8.0: Common Table Expressions
MySQL 8.0: Common Table Expressions MySQL 8.0: Common Table Expressions
MySQL 8.0: Common Table Expressions oysteing
 
MySQL 8.0: GIS — Are you ready?
MySQL 8.0: GIS — Are you ready?MySQL 8.0: GIS — Are you ready?
MySQL 8.0: GIS — Are you ready?Norvald Ryeng
 
MySQL Server Defaults
MySQL Server DefaultsMySQL Server Defaults
MySQL Server DefaultsMorgan Tocker
 
MySQL 8.0 & Unicode: Why, what & how
MySQL 8.0 & Unicode: Why, what & howMySQL 8.0 & Unicode: Why, what & how
MySQL 8.0 & Unicode: Why, what & howBernt Marius Johnsen
 
What you wanted to know about MySQL, but could not find using inernal instrum...
What you wanted to know about MySQL, but could not find using inernal instrum...What you wanted to know about MySQL, but could not find using inernal instrum...
What you wanted to know about MySQL, but could not find using inernal instrum...Sveta Smirnova
 
Proxysql use case scenarios fosdem17
Proxysql use case scenarios    fosdem17Proxysql use case scenarios    fosdem17
Proxysql use case scenarios fosdem17Alkin Tezuysal
 
SQL window functions for MySQL
SQL window functions for MySQLSQL window functions for MySQL
SQL window functions for MySQLDag H. Wanvik
 
How Booking.com avoids and deals with replication lag
How Booking.com avoids and deals with replication lagHow Booking.com avoids and deals with replication lag
How Booking.com avoids and deals with replication lagJean-François Gagné
 
MySQL Group Replication
MySQL Group ReplicationMySQL Group Replication
MySQL Group ReplicationKenny Gryp
 
How to Analyze and Tune MySQL Queries for Better Performance
How to Analyze and Tune MySQL Queries for Better PerformanceHow to Analyze and Tune MySQL Queries for Better Performance
How to Analyze and Tune MySQL Queries for Better Performanceoysteing
 
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
 
Jeudis du Libre - MySQL InnoDB Cluster
Jeudis du Libre - MySQL InnoDB ClusterJeudis du Libre - MySQL InnoDB Cluster
Jeudis du Libre - MySQL InnoDB ClusterFrederic Descamps
 
Jeudis du Libre - MySQL comme Document Store
Jeudis du Libre - MySQL comme Document StoreJeudis du Libre - MySQL comme Document Store
Jeudis du Libre - MySQL comme Document StoreFrederic Descamps
 
How to analyze and tune sql queries for better performance
How to analyze and tune sql queries for better performanceHow to analyze and tune sql queries for better performance
How to analyze and tune sql queries for better performanceoysteing
 
Performance schema and sys schema
Performance schema and sys schemaPerformance schema and sys schema
Performance schema and sys schemaMark Leith
 
MySQL sys schema deep dive
MySQL sys schema deep diveMySQL sys schema deep dive
MySQL sys schema deep diveMark Leith
 
Instrumenting plugins for Performance Schema
Instrumenting plugins for Performance SchemaInstrumenting plugins for Performance Schema
Instrumenting plugins for Performance SchemaMark Leith
 
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
 
MySQL 8.0: Common Table Expressions
MySQL 8.0: Common Table ExpressionsMySQL 8.0: Common Table Expressions
MySQL 8.0: Common Table Expressionsoysteing
 
MySQL Cloud Service Deep Dive
MySQL Cloud Service Deep DiveMySQL Cloud Service Deep Dive
MySQL Cloud Service Deep DiveMorgan Tocker
 

En vedette (20)

MySQL 8.0: Common Table Expressions
MySQL 8.0: Common Table Expressions MySQL 8.0: Common Table Expressions
MySQL 8.0: Common Table Expressions
 
MySQL 8.0: GIS — Are you ready?
MySQL 8.0: GIS — Are you ready?MySQL 8.0: GIS — Are you ready?
MySQL 8.0: GIS — Are you ready?
 
MySQL Server Defaults
MySQL Server DefaultsMySQL Server Defaults
MySQL Server Defaults
 
MySQL 8.0 & Unicode: Why, what & how
MySQL 8.0 & Unicode: Why, what & howMySQL 8.0 & Unicode: Why, what & how
MySQL 8.0 & Unicode: Why, what & how
 
What you wanted to know about MySQL, but could not find using inernal instrum...
What you wanted to know about MySQL, but could not find using inernal instrum...What you wanted to know about MySQL, but could not find using inernal instrum...
What you wanted to know about MySQL, but could not find using inernal instrum...
 
Proxysql use case scenarios fosdem17
Proxysql use case scenarios    fosdem17Proxysql use case scenarios    fosdem17
Proxysql use case scenarios fosdem17
 
SQL window functions for MySQL
SQL window functions for MySQLSQL window functions for MySQL
SQL window functions for MySQL
 
How Booking.com avoids and deals with replication lag
How Booking.com avoids and deals with replication lagHow Booking.com avoids and deals with replication lag
How Booking.com avoids and deals with replication lag
 
MySQL Group Replication
MySQL Group ReplicationMySQL Group Replication
MySQL Group Replication
 
How to Analyze and Tune MySQL Queries for Better Performance
How to Analyze and Tune MySQL Queries for Better PerformanceHow to Analyze and Tune MySQL Queries for Better Performance
How to Analyze and Tune MySQL Queries for Better Performance
 
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
 
Jeudis du Libre - MySQL InnoDB Cluster
Jeudis du Libre - MySQL InnoDB ClusterJeudis du Libre - MySQL InnoDB Cluster
Jeudis du Libre - MySQL InnoDB Cluster
 
Jeudis du Libre - MySQL comme Document Store
Jeudis du Libre - MySQL comme Document StoreJeudis du Libre - MySQL comme Document Store
Jeudis du Libre - MySQL comme Document Store
 
How to analyze and tune sql queries for better performance
How to analyze and tune sql queries for better performanceHow to analyze and tune sql queries for better performance
How to analyze and tune sql queries for better performance
 
Performance schema and sys schema
Performance schema and sys schemaPerformance schema and sys schema
Performance schema and sys schema
 
MySQL sys schema deep dive
MySQL sys schema deep diveMySQL sys schema deep dive
MySQL sys schema deep dive
 
Instrumenting plugins for Performance Schema
Instrumenting plugins for Performance SchemaInstrumenting plugins for Performance Schema
Instrumenting plugins for Performance Schema
 
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
 
MySQL 8.0: Common Table Expressions
MySQL 8.0: Common Table ExpressionsMySQL 8.0: Common Table Expressions
MySQL 8.0: Common Table Expressions
 
MySQL Cloud Service Deep Dive
MySQL Cloud Service Deep DiveMySQL Cloud Service Deep Dive
MySQL Cloud Service Deep Dive
 

Similaire à Using Optimizer Hints to Improve MySQL Query Performance

Applied Partitioning And Scaling Your Database System Presentation
Applied Partitioning And Scaling Your Database System PresentationApplied Partitioning And Scaling Your Database System Presentation
Applied Partitioning And Scaling Your Database System PresentationRichard Crowley
 
MariaDB: ANALYZE for statements (lightning talk)
MariaDB:  ANALYZE for statements (lightning talk)MariaDB:  ANALYZE for statements (lightning talk)
MariaDB: ANALYZE for statements (lightning talk)Sergey Petrunya
 
15 protips for mysql users pfz
15 protips for mysql users   pfz15 protips for mysql users   pfz
15 protips for mysql users pfzJoshua Thijssen
 
16 MySQL Optimization #burningkeyboards
16 MySQL Optimization #burningkeyboards16 MySQL Optimization #burningkeyboards
16 MySQL Optimization #burningkeyboardsDenis Ristic
 
Need for Speed: MySQL Indexing
Need for Speed: MySQL IndexingNeed for Speed: MySQL Indexing
Need for Speed: MySQL IndexingMYXPLAIN
 
ANALYZE for Statements - MariaDB's hidden gem
ANALYZE for Statements - MariaDB's hidden gemANALYZE for Statements - MariaDB's hidden gem
ANALYZE for Statements - MariaDB's hidden gemSergey Petrunya
 
Performance Schema for MySQL Troubleshooting
Performance Schema for MySQL TroubleshootingPerformance Schema for MySQL Troubleshooting
Performance Schema for MySQL TroubleshootingSveta Smirnova
 
New index features in MySQL 8
New index features in MySQL 8New index features in MySQL 8
New index features in MySQL 8Erik Frøseth
 
My sql 5.7-upcoming-changes-v2
My sql 5.7-upcoming-changes-v2My sql 5.7-upcoming-changes-v2
My sql 5.7-upcoming-changes-v2Morgan Tocker
 
4. Data Manipulation.ppt
4. Data Manipulation.ppt4. Data Manipulation.ppt
4. Data Manipulation.pptKISHOYIANKISH
 
MySQL/MariaDB query optimizer tuning tutorial from Percona Live 2013
MySQL/MariaDB query optimizer tuning tutorial from Percona Live 2013MySQL/MariaDB query optimizer tuning tutorial from Percona Live 2013
MySQL/MariaDB query optimizer tuning tutorial from Percona Live 2013Sergey Petrunya
 
ANALYZE for executable statements - a new way to do optimizer troubleshooting...
ANALYZE for executable statements - a new way to do optimizer troubleshooting...ANALYZE for executable statements - a new way to do optimizer troubleshooting...
ANALYZE for executable statements - a new way to do optimizer troubleshooting...Sergey Petrunya
 
Percona Live Europe 2018 MySQL Group Replication... the magic explained
Percona Live Europe 2018  MySQL Group Replication... the magic explainedPercona Live Europe 2018  MySQL Group Replication... the magic explained
Percona Live Europe 2018 MySQL Group Replication... the magic explainedFrederic Descamps
 
Cruel (SQL) Intentions
Cruel (SQL) IntentionsCruel (SQL) Intentions
Cruel (SQL) Intentionsezra_c
 
MySQL Kitchen : spice up your everyday SQL queries
MySQL Kitchen : spice up your everyday SQL queriesMySQL Kitchen : spice up your everyday SQL queries
MySQL Kitchen : spice up your everyday SQL queriesDamien Seguy
 
Window functions in MySQL 8.0
Window functions in MySQL 8.0Window functions in MySQL 8.0
Window functions in MySQL 8.0Mydbops
 
DATA BASE || INTRODUCTION OF DATABASE \\ SQL 2018
DATA BASE || INTRODUCTION OF DATABASE \\ SQL 2018DATA BASE || INTRODUCTION OF DATABASE \\ SQL 2018
DATA BASE || INTRODUCTION OF DATABASE \\ SQL 2018teachersduniya.com
 
Advanced Query Optimizer Tuning and Analysis
Advanced Query Optimizer Tuning and AnalysisAdvanced Query Optimizer Tuning and Analysis
Advanced Query Optimizer Tuning and AnalysisMYXPLAIN
 

Similaire à Using Optimizer Hints to Improve MySQL Query Performance (20)

Applied Partitioning And Scaling Your Database System Presentation
Applied Partitioning And Scaling Your Database System PresentationApplied Partitioning And Scaling Your Database System Presentation
Applied Partitioning And Scaling Your Database System Presentation
 
Explain
ExplainExplain
Explain
 
MariaDB: ANALYZE for statements (lightning talk)
MariaDB:  ANALYZE for statements (lightning talk)MariaDB:  ANALYZE for statements (lightning talk)
MariaDB: ANALYZE for statements (lightning talk)
 
15 protips for mysql users pfz
15 protips for mysql users   pfz15 protips for mysql users   pfz
15 protips for mysql users pfz
 
16 MySQL Optimization #burningkeyboards
16 MySQL Optimization #burningkeyboards16 MySQL Optimization #burningkeyboards
16 MySQL Optimization #burningkeyboards
 
Need for Speed: MySQL Indexing
Need for Speed: MySQL IndexingNeed for Speed: MySQL Indexing
Need for Speed: MySQL Indexing
 
ANALYZE for Statements - MariaDB's hidden gem
ANALYZE for Statements - MariaDB's hidden gemANALYZE for Statements - MariaDB's hidden gem
ANALYZE for Statements - MariaDB's hidden gem
 
Performance Schema for MySQL Troubleshooting
Performance Schema for MySQL TroubleshootingPerformance Schema for MySQL Troubleshooting
Performance Schema for MySQL Troubleshooting
 
New index features in MySQL 8
New index features in MySQL 8New index features in MySQL 8
New index features in MySQL 8
 
My sql 5.7-upcoming-changes-v2
My sql 5.7-upcoming-changes-v2My sql 5.7-upcoming-changes-v2
My sql 5.7-upcoming-changes-v2
 
4. Data Manipulation.ppt
4. Data Manipulation.ppt4. Data Manipulation.ppt
4. Data Manipulation.ppt
 
MySQL/MariaDB query optimizer tuning tutorial from Percona Live 2013
MySQL/MariaDB query optimizer tuning tutorial from Percona Live 2013MySQL/MariaDB query optimizer tuning tutorial from Percona Live 2013
MySQL/MariaDB query optimizer tuning tutorial from Percona Live 2013
 
ANALYZE for executable statements - a new way to do optimizer troubleshooting...
ANALYZE for executable statements - a new way to do optimizer troubleshooting...ANALYZE for executable statements - a new way to do optimizer troubleshooting...
ANALYZE for executable statements - a new way to do optimizer troubleshooting...
 
Percona Live Europe 2018 MySQL Group Replication... the magic explained
Percona Live Europe 2018  MySQL Group Replication... the magic explainedPercona Live Europe 2018  MySQL Group Replication... the magic explained
Percona Live Europe 2018 MySQL Group Replication... the magic explained
 
Cruel (SQL) Intentions
Cruel (SQL) IntentionsCruel (SQL) Intentions
Cruel (SQL) Intentions
 
MySQL Kitchen : spice up your everyday SQL queries
MySQL Kitchen : spice up your everyday SQL queriesMySQL Kitchen : spice up your everyday SQL queries
MySQL Kitchen : spice up your everyday SQL queries
 
Window functions in MySQL 8.0
Window functions in MySQL 8.0Window functions in MySQL 8.0
Window functions in MySQL 8.0
 
Perf Tuning Short
Perf Tuning ShortPerf Tuning Short
Perf Tuning Short
 
DATA BASE || INTRODUCTION OF DATABASE \\ SQL 2018
DATA BASE || INTRODUCTION OF DATABASE \\ SQL 2018DATA BASE || INTRODUCTION OF DATABASE \\ SQL 2018
DATA BASE || INTRODUCTION OF DATABASE \\ SQL 2018
 
Advanced Query Optimizer Tuning and Analysis
Advanced Query Optimizer Tuning and AnalysisAdvanced Query Optimizer Tuning and Analysis
Advanced Query Optimizer Tuning and Analysis
 

Plus de oysteing

POLARDB: A database architecture for the cloud
POLARDB: A database architecture for the cloudPOLARDB: A database architecture for the cloud
POLARDB: A database architecture for the cloudoysteing
 
POLARDB: A database architecture for the cloud
POLARDB: A database architecture for the cloudPOLARDB: A database architecture for the cloud
POLARDB: A database architecture for the cloudoysteing
 
POLARDB for MySQL - Parallel Query
POLARDB for MySQL - Parallel QueryPOLARDB for MySQL - Parallel Query
POLARDB for MySQL - Parallel Queryoysteing
 
JSON_TABLE -- The best of both worlds
JSON_TABLE -- The best of both worldsJSON_TABLE -- The best of both worlds
JSON_TABLE -- The best of both worldsoysteing
 
Histogram Support in MySQL 8.0
Histogram Support in MySQL 8.0Histogram Support in MySQL 8.0
Histogram Support 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.0oysteing
 
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
 
How to analyze and tune sql queries for better performance vts2016
How to analyze and tune sql queries for better performance vts2016How to analyze and tune sql queries for better performance vts2016
How to analyze and tune sql queries for better performance vts2016oysteing
 

Plus de oysteing (8)

POLARDB: A database architecture for the cloud
POLARDB: A database architecture for the cloudPOLARDB: A database architecture for the cloud
POLARDB: A database architecture for the cloud
 
POLARDB: A database architecture for the cloud
POLARDB: A database architecture for the cloudPOLARDB: A database architecture for the cloud
POLARDB: A database architecture for the cloud
 
POLARDB for MySQL - Parallel Query
POLARDB for MySQL - Parallel QueryPOLARDB for MySQL - Parallel Query
POLARDB for MySQL - Parallel Query
 
JSON_TABLE -- The best of both worlds
JSON_TABLE -- The best of both worldsJSON_TABLE -- The best of both worlds
JSON_TABLE -- The best of both worlds
 
Histogram Support in MySQL 8.0
Histogram Support in MySQL 8.0Histogram Support in MySQL 8.0
Histogram Support 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
 
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
 
How to analyze and tune sql queries for better performance vts2016
How to analyze and tune sql queries for better performance vts2016How to analyze and tune sql queries for better performance vts2016
How to analyze and tune sql queries for better performance vts2016
 

Dernier

Active Directory Penetration Testing, cionsystems.com.pdf
Active Directory Penetration Testing, cionsystems.com.pdfActive Directory Penetration Testing, cionsystems.com.pdf
Active Directory Penetration Testing, cionsystems.com.pdfCionsystems
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️anilsa9823
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxbodapatigopi8531
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about usDynamic Netsoft
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionSolGuruz
 
Clustering techniques data mining book ....
Clustering techniques data mining book ....Clustering techniques data mining book ....
Clustering techniques data mining book ....ShaimaaMohamedGalal
 
Test Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and BackendTest Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and BackendArshad QA
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AIABDERRAOUF MEHENNI
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...panagenda
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software DevelopersVinodh Ram
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsAndolasoft Inc
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfjoe51371421
 
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
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comFatema Valibhai
 

Dernier (20)

Active Directory Penetration Testing, cionsystems.com.pdf
Active Directory Penetration Testing, cionsystems.com.pdfActive Directory Penetration Testing, cionsystems.com.pdf
Active Directory Penetration Testing, cionsystems.com.pdf
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptx
 
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS LiveVip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about us
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with Precision
 
Clustering techniques data mining book ....
Clustering techniques data mining book ....Clustering techniques data mining book ....
Clustering techniques data mining book ....
 
Test Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and BackendTest Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and Backend
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software Developers
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.js
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdf
 
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 🔝✔️✔️
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 

Using Optimizer Hints to Improve MySQL Query Performance

  • 1. Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | Using Optimizer Hints to Improve MySQL Query Performance Øystein Grøvlen Senior Principal Software Engineer MySQL Optimizer Team, Oracle Copyright © 2016, Oracle and/or its affiliates. All rights reserved.
  • 2. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. Program Agenda Introduction to optimizer hints Index hints Join order hints Subquery hints Hints and query rewrite plugin 1 2 3 4 5
  • 3. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. Program Agenda Introduction to optimizer hints Index hints Join order hints Subquery hints Hints and query rewrite plugin 1 2 3 4 5
  • 4. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. MySQL Optimizer SELECT a, b FROM t1, t2, t3 WHERE t1.a = t2.b AND t2.b = t3.c AND t2.d > 20 AND t2.d < 30; MySQL Server Cost based optimizations Heuristics Cost Model Optimizer Table/index info (data dictionary) Statistics (storage engines) t2 t3 t1 Table scan Range scan Ref access JOIN JOIN
  • 5. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. Influencing the Optimizer with Hints • Limit which indexes may be used: – USE INDEX, FORCE INDEX, IGNORE INDEX • Force specific join order: – STRAIGHT_JOIN • New optimizer hints (MySQL 5.7) – Syntax: SELECT /*+ HINT1(args) HINT2(args) */ … FROM … – May be used for SELECT/UPDATE/INSERT/DELETE statements – May also be used in sub-queries When the optimizer does not pick the best query plan
  • 6. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. New Optimizer Hints • Hints in 5.7: – BKA(tables)/NO_BKA(tables), BNL(tables)/NO_BNL(tables) – MRR(table indexes)/NO_MRR(table indexes) – SEMIJOIN/NO_SEMIJOIN(strategies), SUBQUERY(strategy) – NO_ICP(table indexes) – NO_RANGE_OPTIMIZATION(table indexes) – QB_NAME(name) • Hints in 8.0.0 Optimizer Labs Release – MERGE(views)/NO_MERGE(views) – JOIN_ORDER(tables) JOIN_PREFIX(tables) JOIN_SUFFIX(tables) JOIN_FIXED_ORDER()
  • 7. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. Optimizer Hints • Comment syntax: – Portable: Will not fail if server does not support optimizer hint • Warnings on – Syntax errors in hint – Symbols not found – Hint conflicts • If conflicting hints, first hint will be accepted • EXPLAIN warning shows which hint was accepted – Note: No warning if hint is accepted, but is not applicable Warnings not errors
  • 8. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. Optimizer Hints mysql> EXPLAIN SELECT /*+ MRR(orders) */ SUM(o_totalprice) FROM orders WHERE o_orderdate BETWEEN '1994-06-17' AND '1994-06-22'; +----+-------------+--------+------------+-------+---------------+---------------+---------+------+--- ----+----------+----------------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+--------+------------+-------+---------------+---------------+---------+------+--- ----+----------+----------------------------------+ | 1 | SIMPLE | orders | NULL | range | i_o_orderdate | i_o_orderdate | 4 | NULL | 68584 | 100.00 | Using index condition; Using MRR | +----+-------------+--------+------------+-------+---------------+---------------+---------+------+--- ----+----------+----------------------------------+ 1 row in set, 1 warning (0,01 sec) Note (Code 1003): /* select#1 */ select /*+ MRR(`orders`@`select#1`) */ sum(`dbt3`.`orders`.`o_totalprice`) AS `sum(o_totalprice)` from `dbt3`.`orders` where (`dbt3`.`orders`.`o_orderDATE` between '1994-06-17' and '1994-06-22') Example
  • 9. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. Optimizer Hints mysql> EXPLAIN SELECT /*+ MRR(orders) NO_ICP(orders i_o_orderdate) */ SUM(o_totalprice) FROM orders WHERE o_orderdate BETWEEN '1994-06-17' AND '1994-06-22'; +----+-------------+--------+------------+-------+---------------+---------------+---------+------+--- ----+----------+----------------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+--------+------------+-------+---------------+---------------+---------+------+--- ----+----------+----------------------------------+ | 1 | SIMPLE | orders | NULL | range | i_o_orderdate | i_o_orderdate | 4 | NULL | 68584 | 100.00 | Using where; Using MRR | +----+-------------+--------+------------+-------+---------------+---------------+---------+------+--- ----+----------+----------------------------------+ 1 row in set, 1 warning (0,01 sec) Note (Code 1003): /* select#1 */ select /*+ MRR(`orders`@`select#1`) NO_ICP(`orders`@`select#1` `i_o_orderdate`) */ sum(`dbt3`.`orders`.`o_totalprice`) AS `sum(o_totalprice)` from `dbt3`.`orders` where (`dbt3`.`orders`.`o_orderDATE` between '1994-06-17' and '1994-06-22') Example: Multiple hints
  • 10. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. Optimizer Hints mysql> EXPLAIN SELECT /*+ MRR(t1) */ SUM(o_totalprice) FROM orders WHERE o_orderdate BETWEEN '1994-06-17' AND '1994-06-22'; +----+-------------+--------+------------+-------+---------------+---------------+---------+------+--- ----+----------+----------------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+--------+------------+-------+---------------+---------------+---------+------+--- ----+----------+----------------------------------+ | 1 | SIMPLE | orders | NULL | range | i_o_orderdate | i_o_orderdate | 4 | NULL | 68584 | 100.00 | Using index condition | +----+-------------+--------+------------+-------+---------------+---------------+---------+------+--- ----+----------+----------------------------------+ 1 row in set, 1 warning (0,01 sec) Warning (Code 3128): Unresolved name `t1`@`select#1` for MRR hint Note (Code 1003): /* select#1 */ select sum(`dbt3`.`orders`.`o_totalprice`) AS `sum(o_totalprice)` from `dbt3`.`orders` where (`dbt3`.`orders`.`o_orderDATE` between '1994-06-17' and '1994-06-22') Example: Unresolved names
  • 11. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. Optimizer Hints mysql> EXPLAIN SELECT /*+ MRR(orders) NO_MRR(orders) */ SUM(o_totalprice) FROM orders WHERE o_orderdate BETWEEN '1994-06-17' AND '1994-06-22'; +----+-------------+--------+------------+-------+---------------+---------------+---------+------+--- ----+----------+----------------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+--------+------------+-------+---------------+---------------+---------+------+--- ----+----------+----------------------------------+ | 1 | SIMPLE | orders | NULL | range | i_o_orderdate | i_o_orderdate | 4 | NULL | 68584 | 100.00 | Using index condition; Using MRR | +----+-------------+--------+------------+-------+---------------+---------------+---------+------+--- ----+----------+----------------------------------+ 1 row in set, 1 warning (0,01 sec) Warning (Code 3126): Hint NO_MRR(`orders` ) is ignored as conflicting/duplicated Note (Code 1003): /* select#1 */ select /*+ MRR(`orders`@`select#1`) */ sum(`dbt3`.`orders`.`o_totalprice`) AS `sum(o_totalprice)` from `dbt3`.`orders` where (`dbt3`.`orders`.`o_orderDATE` between '1994-06-17' and '1994-06-22') Example: Conflicting hints
  • 12. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. Optimizer Hints mysql> EXPLAIN SELECT /*+ MRR(orders) */ SUM(o_totalprice) FROM orders WHERE o_orderdate = '1994-06-17'; +----+-------------+--------+------------+------+---------------+---------------+---------+-------+--- ---+----------+-------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+--------+------------+------+---------------+---------------+---------+-------+--- ---+----------+-------+ | 1 | SIMPLE | orders | NULL | ref | i_o_orderdate | i_o_orderdate | 4 | const | 6440 | 100.00 | NULL | +----+-------------+--------+------------+------+---------------+---------------+---------+-------+--- ---+----------+-------+ 1 row in set, 1 warning (0,00 sec) Note (Code 1003): /* select#1 */ select /*+ MRR(`orders`@`select#1`) */ sum(`dbt3`.`orders`.`o_totalprice`) AS `sum(o_totalprice)` from `dbt3`.`orders` where (`dbt3`.`orders`.`o_orderDATE` = '1994-06-17') Example: Hint not applicable
  • 13. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. Optimizer Hints • Hints we consider to add – Force/ignore index_merge alternatives – Reimplement index hints in new syntax – Hints within views – Temporarily set session variables for just one query Future plans
  • 14. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. Program Agenda Introduction to optimizer hints Index hints Join order hints Subquery hints Hints and query rewrite plugin 1 2 3 4 5
  • 15. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. Index hints • USE INDEX (index_list) – Restrict which indexes are considered – Table scan may be used • FORCE INDEX(index_list) – Use one of the specified indexes – Table scan may only be used if none of the indexes are applicable • IGNORE INDEX(index_list) – Do not use the specified index • Follows table name in FROM clause ... FROM t1 IGNORE INDEX(idx1) ... Confidential – Oracle Internal/Restricted/Highly Restricted 15
  • 16. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. Index Hints Table scan: • IO-cost: #pages in table * IO_BLOCK_READ_COST • CPU cost: #rows * ROW_EVALUATE_COST Range scan (on secondary index): • IO-cost: #rows_in_range * IO_BLOCK_READ_COST • CPU cost: #rows_in_range * ROW_EVALUATE_COST Example SELECT SUM(o_totalprice) FROM orders WHERE o_orderdate BETWEEN '1994-01-01' AND '1994-12-31';
  • 17. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. Table Scan or Index Range Scan? EXPLAIN SELECT SUM(o_totalprice) FROM orders WHERE o_orderdate BETWEEN '1994-01-01' AND '1994-12-31'; EXPLAIN SELECT SUM(o_totalprice) FROM orders WHERE o_orderdate BETWEEN '1994-01-01' AND '1994-06-30'; id select type table type possible keys key key len ref rows extra 1 SIMPLE orders ALL i_o_orderdate NULL NULL NULL 15000000 Using where Id select type table type possible keys key key len ref rows extra 1 SIMPLE orders range i_o_orderdate i_o_orderdate 4 NULL 2235118 Using index condition
  • 18. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. Cost Model vs Real World Data in Memory Data on Disk Data on SSD Table scan 6.8 seconds 36 seconds 15 seconds Index scan 5.2 seconds 2.5 hours 30 minutes Measured Execution Times Force Index Scan with a hint: SELECT SUM(o_totalprice) FROM orders FORCE INDEX (i_o_orderdate) WHERE o_orderdate BETWEEN '1994-01-01' AND '1994-12-31';
  • 19. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. Index Merge Intersection • Combine several indexes to reduce number of (or avoid) accesses to base table for ANDed conditions • Example: SELECT * FROM t1 WHERE a=10 AND b=10 • Index Merge Intersection: 10INDEX(a) 10INDEX(b) a=10 AND b=10Result: Intersection
  • 20. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. Index Merge Intersection SELECT count(*) FROM user WHERE user_type=2 AND status=1 AND parent_id=0; Beware of low-selectivity indexes! id select type table type possible keys key key len ref rows Extra 1 SIMPLE user index_ merge parent_id, status, user_type user_type, status, parent_id 1,1,4 NULL 3696 Using intersect (user_type, status, parent_id); Using where; Using index mysql> SELECT count(*) FROM user WHERE user_type=2 AND status=1 … ... 1 row in set (5.33 sec) mysql> SELECT count(*) FROM user USE INDEX (user_type) WHERE user_type=2 … ... 1 row in set (0.09 sec) Low selectivity Source: http://www.mysqlperformanceblog.com/2012/12/14/ the-optimization-that-often-isnt-index-merge-intersection/
  • 21. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. Index Merge Intersection mysql> FLUSH STATUS; mysql> SELECT count(*) FROM user WHERE user_type=2 AND status=1 AND parent_id=0; ... 1 row in set (5.28 sec) mysql> SHOW STATUS LIKE 'Handler_read%'; +-----------------------+----------+ | Variable_name | Value | +-----------------------+----------+ | Handler_read_first | 0 | | Handler_read_key | 3 | | Handler_read_last | 0 | | Handler_read_next | 15825904 | | Handler_read_prev | 0 | | Handler_read_rnd | 0 | | Handler_read_rnd_next | 0 | +-----------------------+----------+ Handler status variables mysql> FLUSH STATUS; mysql> SELECT count(*) FROM user USE INDEX (user_id) WHERE user_type=2 AND status=1 AND parent_id=0; ... 1 row in set (0.09 sec) mysql> SHOW STATUS LIKE 'Handler_read%‘; +-----------------------+-------+ | Variable_name | Value | +-----------------------+-------+ | Handler_read_first | 0 | | Handler_read_key | 1 | | Handler_read_last | 0 | | Handler_read_next | 23312 | | Handler_read_prev | 0 | | Handler_read_rnd | 0 | | Handler_read_rnd_next | 0 | +-----------------------+-------+
  • 22. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. Program Agenda Introduction to optimizer hints Index hints Join order hints Subquery hints Hints and query rewrite plugin 1 2 3 4 5
  • 23. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. Join order hints • Specify complete join order SELECT STRAIGHT_JOIN ... FROM t1 JOIN t2 JOIN t3 ... • Specify order of two tables SELECT ... FROM t1 STRAIGHT_JOIN t2 JOIN t3 ... • New join order hints in MySQL 8.0 – Full order: SELECT /*+ JOIN_FIXED_ORDER() */ ... FROM t1 JOIN t2 JOIN t3 ... – Partial order: SELECT /*+ JOIN_ORDER(t1, t2) */ ... FROM t1 JOIN t2 JOIN t3 ... – First tables: SELECT /*+ JOIN_PREFIX(t1) */ ... FROM t1 JOIN t2 JOIN t3 ... – Last tables: SELECT /*+ JOIN_SUFFIX(t1) */ ... FROM t1 JOIN t2 JOIN t3 ... – Confidential – Oracle Internal/Restricted/Highly Restricted 23
  • 24. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. Join Optimizer Example EXPLAIN SELECT * FROM orders JOIN customer ON o_custkey = c_custkey WHERE o_orderdate < '1993-01-01' AND c_acctbal < -1000; id select type table type possible keys key key len ref rows filtered Extra 1 SIMPLE orders ALL i_o_orderdate, i_o_custkey NULL NULL NULL 15000000 31.19 Using where 1 SIMPLE customer eq_ ref PRIMARY PRIMARY 4 dbt3.orders. o_custkey 1 33.33 Using where
  • 25. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. Join Optimizer Change join order with a hint EXPLAIN SELECT /*+ JOIN_PREFIX(customer) */ * FROM orders JOIN customer ON o_custkey = c_custkey WHERE o_orderdate < '1993-01-01' AND c_acctbal < -1000; id select type table type possible keys key key len ref rows filtered extra 1 SIMPLE customer ALL PRIMARY NULL NULL NULL 1500000 33.33 Using where 1 SIMPLE Orders ref i_o_orderdate, i_o_custkey PRIM ARY 4 dbt3.orders. o_custkey 1 33.33 Using where id select type table type possible keys key key len ref rows filtered Extra 1 SIMPLE customer ALL PRIMARY NULL NULL NULL 1500000 33.33 Using where 1 SIMPLE orders ref i_o_orderdate, i_o_custkey i_o_custkey 5 dbt3. customer. c_custkey 15 31.19 Using where Alternative hints with same effect: JOIN_ORDER(customer, orders) JOIN_SUFFIX(orders)
  • 26. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. Join Order 0 2 4 6 8 10 12 14 16 QueryExecutionTime(seconds) orders → customer customer → orders Performance
  • 27. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. DBT-3 Query 8 SELECT o_year, SUM(CASE WHEN nation = 'FRANCE' THEN volume ELSE 0 END) / SUM(volume) AS mkt_share FROM ( SELECT EXTRACT(YEAR FROM o_orderdate) AS o_year, l_extendedprice * (1 - l_discount) AS volume, n2.n_name AS nation FROM part JOIN lineitem ON p_partkey = l_partkey JOIN supplier ON s_suppkey = l_suppkey JOIN orders ON l_orderkey = o_orderkey JOIN customer ON o_custkey = c_custkey JOIN nation n1 ON c_nationkey = n1.n_nationkey JOIN region ON n1.n_regionkey = r_regionkey JOIN nation n2 ON s_nationkey = n2.n_nationkey WHERE r_name = 'EUROPE' AND o_orderdate BETWEEN '1995-01-01' AND '1996-12-31' AND p_type = 'PROMO BRUSHED STEEL' ) AS all_nations GROUP BY o_year ORDER BY o_year; National Market Share Query
  • 28. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. DBT-3 Query 8 MySQL Workbench: Visual EXPLAIN (MySQL 5.6) Execution time: 21 seconds
  • 29. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. DBT-3 Query 8 SELECT o_year, SUM(CASE WHEN nation = 'FRANCE' THEN volume ELSE 0 END) / SUM(volume) AS mkt_share FROM ( SELECT EXTRACT(YEAR FROM o_orderdate) AS o_year, l_extendedprice * (1 - l_discount) AS volume, n2.n_name AS nation FROM part STRAIGHT_JOIN lineitem ON p_partkey = l_partkey JOIN supplier ON s_suppkey = l_suppkey JOIN orders ON l_orderkey = o_orderkey JOIN customer ON o_custkey = c_custkey JOIN nation n1 ON c_nationkey = n1.n_nationkey JOIN region ON n1.n_regionkey = r_regionkey JOIN nation n2 ON s_nationkey = n2.n_nationkey WHERE r_name = 'EUROPE' AND o_orderdate BETWEEN '1995-01-01' AND '1996-12-31' AND p_type = 'PROMO BRUSHED STEEL' ) AS all_nations GROUP BY o_year ORDER BY o_year; Force early processing of high selectivity conditions Highest selectivity part before lineitem
  • 30. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. DBT-3 Query 8 Improved join order Execution time: 3 seconds
  • 31. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. MySQL 5.7: Improved join order Improvements to Query 8 in MySQL 5.7: • Filtering on non-indexed columns are taken into account – No need for hint to force part table to be processed early • Merge derived tables into outer query – No temporary table
  • 32. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. Program Agenda Introduction to optimizer hints Index hints Join order hints Subquery hints Hints and query rewrite plugin 1 2 3 4 5
  • 33. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. Subquery category: • IN (SELECT …) • NOT IN (SELECT …) • FROM (SELECT …) • <CompOp> ALL/ANY (SELECT ..) • EXISTS/other Strategy: Overview of Subquery Optimizations • Semi-join • Materialization • IN ➜ EXISTS • Merged • Materialized • MAX/MIN re-write • Execute subquery New in MySQL 5.7
  • 34. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. Derived Tables • Subquery in FROM clause SELECT AVG(o_totalprice) FROM ( SELECT * FROM orders ORDER BY o_totalprice DESC LIMIT 100000 ) td; • MySQL 5.6 and earlier: Executed separately and result stored in a temporary table (materialization) • MySQL 5.6 and later: If useful, index will be created on the temporary table • MySQL 5.7: Treat derived tables like views: May be merged with outer query block
  • 35. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. Derived Tables SELECT * FROM part p1 JOIN (SELECT * FROM part WHERE p_type LIKE '%STEEL%') p2 ON p1.p_name = p2.p_name WHERE p1.p_type LIKE '%COPPER%'; Example MySQL 5.5 MySQL 5.6 MySQL 5.7 0.4 seconds 6 minutes
  • 36. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. Hint: Merge/Materialize Derived Table or View • Derived tables/views are, if possible, merged into outer query • NO_MERGE hint can be used to override default behavior: SELECT /*+ NO_MERGE(dt) */ * FROM t1 JOIN (SELECT x, y FROM t2) dt ON t1.x = dt.x; • MERGE hint will force a merge SELECT /*+ MERGE(dt) */ * FROM t1 JOIN (SELECT x, y FROM t2) dt ON t1.x = dt.x; • Can also use MERGE/NO_MERGE hints for views SELECT /*+ NO_MERGE(v) */ * FROM t1 JOIN v ON t1.x = v.x; Confidential – Oracle Internal/Restricted/Highly Restricted 36 MySQL 8.0.0 optimizer labs release
  • 37. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. Derived Tables SELECT /*+ NO_MERGE(p2) */ * FROM part p1 JOIN (SELECT * FROM part WHERE p_type LIKE '%STEEL%') p2 ON p1.p_name = p2.p_name WHERE p1.p_type LIKE '%COPPER%'; NO_MERGE hint id select type table type possible keys key key len ref rows Extra 1 PRIMARY p1 ALL NULL NULL NULL NULL 200000 Using where 1 PRIMARY <derived2> ref <auto_key0> <auto_key0> 58 dbt3.p1.p_name 10 NULL 2 DERIVED part ALL NULL NULL NULL NULL 200000 Using where
  • 38. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. Semi-join • Convert IN - subquery to inner join, BUT – Need some way to remove duplicates • Different strategies for duplicate removal: – FirstMatch (equivalent to IN→EXISTS execution) – LooseScan (index scan, skip duplicates) – Materialization: MatLookup (like subquery materialization), MatScan (materialized table is first in join order) – Duplicate WeedOut (insert result rows of semi-join query into temporary table with unique index; duplicate rows will be rejected. Any join order.) • If duplicate removal is not necessary: – Table pull-out
  • 39. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. • Disable semi-join with hint: EXPLAIN SELECT * FROM t2 WHERE t2.a IN (SELECT /*+ NO_SEMIJOIN() */ a FROM t3); • No hint, optimizer chooses semi-join algorithm LooseScan: EXPLAIN SELECT * FROM t2 WHERE t2.a IN (SELECT a FROM t3); MySQL 5.7: Hint Example: SEMIJOIN id select type table type possible keys key key len ref rows Extra 1 SIMPLE t3 index a a 4 NULL 3 Using where; LooseScan 1 SIMPLE t2 ref a a 4 test.t3.a 1 Using index id select type table type possible keys key key len ref rows Extra 1 PRIMARY t2 index null a 4 NULL 4 Using where; Using index 2 DEPENDENT SUBQUERY t3 Index_ subquery a a 4 func 1 Using index
  • 40. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. MySQL 5.7: Hint Example: SEMIJOIN • Force Semi-join Materialization to be used EXPLAIN SELECT /*+ SEMIJOIN(@subq MATERIALIZATION) */ * FROM t2 WHERE t2.a IN (SELECT /*+ QB_NAME(subq) */ a FROM t3); 3 rows in set, 1 warning (0.01 sec) id select type table type possible keys key key len ref rows Extra 1 SIMPLE t2 index a a 4 NULL 4 Using where; Using index 1 SIMPLE <subquery2> eq_ref <auto_key> <auto_key> 4 test.t2.a 1 NULL 2 MATERIALIZED t3 index a a 4 NULL 3 Using index
  • 41. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. SELECT l_orderkey FROM lineitem GROUP BY l_orderkey HAVING SUM(l_quantity) > 313 SELECT o_orderdate, o_totalprice FROM orders WHERE o_orderkey IN ( ); Subquery Materialization 1. Execute subquery once and store result in a temporary table – Table has unique index for quick look-up and duplicate removal. 2. Execute outer query and check for matches in temporary table. Materialize
  • 42. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. Subquery Materialization SELECT o_orderdate, o_totalprice FROM orders WHERE o_orderkey IN ( SELECT l_orderkey FROM lineitem GROUP BY l_orderkey HAVING SUM(l_quantity) > 313); SELECT o_orderdate, o_totalprice FROM orders WHERE o_orderkey IN (SELECT /*+ SUBQUERY(INTOEXISTS)*/ l_orderkey FROM lineitem GROUP BY l_orderkey HAVING SUM(l_quantity) > 313); id select type table type possible keys key key len ref rows Extra 1 PRIMARY orders ALL NULL NULL NULL NULL 1500000 Using where 2 SUBQUERY lineitem index PRIMARY, ... PRIMARY 8 NULL 6001215 NULL id select type table type possible keys key key len ref rows Extra 1 PRIMARY orders ALL NULL NULL NULL NULL 1500000 Using where 2 DEPENDENT SUBQUERY lineitem index PRIMARY, ... PRIMARY 8 NULL 6001215 NULL
  • 43. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. 35,6 0,110 0,126 0,113 8,59 64,0 0 10 20 30 40 50 60 70 QueryExecutionTime(seconds) FirstMatch LooseScan DupsWeedout MatScan Subquery Mat. InToExists SELECT o_totalprice FROM orders WHERE o_orderkey IN (SELECT l_orderkey FROM lineitem WHERE l_shipdate = '1996-09-30'); DBT-3, Scale 10 (23 GB) innodb_buffer_pool_size= 32 GB (CPU-bound) MySQL 5.6: Semi-join: Example
  • 44. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. Program Agenda Introduction to optimizer hints Index hints Join order hints Subquery hints Hints and query rewrite plugin 1 2 3 4 5
  • 45. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. MySQL 5.7: Query Rewrite Plugin • Rewrite problematic queries without the need to make application changes – Add hints – Modify join order – Much more … • Add rewrite rules to table: INSERT INTO query_rewrite.rewrite_rules (pattern, replacement ) VALUES ("SELECT * FROM t1 WHERE a > ? AND b = ?", "SELECT * FROM t1 FORCE INDEX (a_idx) WHERE a > ? AND b = ?"); • New pre- and post-parse query rewrite APIs – Users can write their own plug-ins
  • 46. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. More information • MySQL Server Team blog – http://mysqlserverteam.com/ • My blog: – http://oysteing.blogspot.com/ • Optimizer team blog: – http://mysqloptimizerteam.blogspot.com/ • MySQL forums: – Optimizer & Parser: http://forums.mysql.com/list.php?115 – Performance: http://forums.mysql.com/list.php?24
  • 47. 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. 47