MySQL Query Tuning
Transcript of MySQL Query Tuning
![Page 1: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/1.jpg)
MySQL Query Tuningfor Dev[Op]s. Introduction
![Page 2: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/2.jpg)
•Basics•Indexes
How Do They Work?When MySQL Uses IndexesOptimizer Histograms
•DiagnosticsEXPLAIN: How Optimizer WorksReal Numbers: Inside Storage EngineReal Numbers: Inside the Server
•How to Affect Query Plans
Table ofContents
2 ©2021 Percona
![Page 3: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/3.jpg)
• Sveta Smirnova• MySQL Support engineer• Author of
• MySQL Troubleshooting• JSON UDF functions• FILTER clause for MySQL
• Speaker• Percona Live, OOW, Fosdem,
DevConf, HighLoad...
3 ©2021 Percona
![Page 4: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/4.jpg)
Basics
![Page 5: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/5.jpg)
Concurrency
EnvironmentQuery Tuning
TroubleshootingWorkflow
5 ©2021 Percona
![Page 6: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/6.jpg)
Concurrency
EnvironmentQuery Tuning
TroubleshootingWorkflow: ThisSession
6 ©2021 Percona
![Page 7: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/7.jpg)
$system = System::factory()
->setName($this->form->get(Field::NAME))
->setDescription(
$this->form->get(Field::DESCRIPTION)
);
DAO::system()->take($system);The Query
7 ©2021 Percona
![Page 8: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/8.jpg)
$system = System::factory()
->setName($this->form->get(Field::NAME))
->setDescription(
$this->form->get(Field::DESCRIPTION)
);
DAO::system()->take($system);The Query
7 ©2021 Percona
![Page 9: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/9.jpg)
cursor = conn.cursor()
q = ’’’UPDATE ‘foo‘ SET my_date=NOW(),
subject = %s,
msg = %s,
address = %s,
updated_at = NOW()
WHERE id=%s
’’’
cursor.execute(q, [
remote_resp.get(’subject’),
remote_resp.get(’msg’),
remote_resp.get(’address’),
my_id
])
The Query
7 ©2021 Percona
![Page 10: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/10.jpg)
cursor = conn.cursor()
q = ’’’UPDATE ‘foo‘ SET my_date=NOW(),
subject = %s,
msg = %s,
address = %s,
updated_at = NOW()
WHERE id=%s
’’’
cursor.execute(q, [
remote_resp.get(’subject’),
remote_resp.get(’msg’),
remote_resp.get(’address’),
my_id
])
The Query
7 ©2021 Percona
![Page 11: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/11.jpg)
SELECT dept_name, title, gender,
min(salary) AS mins,
max(salary) AS maxs
FROM employees
JOIN salaries USING(emp_no)
JOIN titles USING(emp_no)
JOIN dept_emp USING(emp_no)
JOIN departments USING(dept_no)
JOIN dept_manager USING(dept_no)
WHERE dept_manager.to_date = ’9999-01-01’
GROUP BY dept_name, title, gender
ORDER BY gender, maxs DESC;
The Query
7 ©2021 Percona
![Page 12: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/12.jpg)
SELECT dept_name, title, gender,
min(salary) AS mins,
max(salary) AS maxs
FROM employees
JOIN salaries USING(emp_no)
JOIN titles USING(emp_no)
JOIN dept_emp USING(emp_no)
JOIN departments USING(dept_no)
JOIN dept_manager USING(dept_no)
WHERE dept_manager.to_date = ’9999-01-01’
GROUP BY dept_name, title, gender
ORDER BY gender, maxs DESC;
The Query
7 ©2021 Percona
![Page 13: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/13.jpg)
• PMM QAN
• Slow Query Log• Application log• ...
Always TuneRaw Query
8 ©2021 Percona
![Page 14: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/14.jpg)
• PMM QAN• Slow Query Log
• Application log• ...
Always TuneRaw Query
8 ©2021 Percona
![Page 15: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/15.jpg)
• PMM QAN• Slow Query Log• Application log
• ...
Always TuneRaw Query
8 ©2021 Percona
![Page 16: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/16.jpg)
• PMM QAN• Slow Query Log• Application log• ...
Always TuneRaw Query
8 ©2021 Percona
![Page 17: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/17.jpg)
• Mind your data!• 75,000,000 rows
• (INT, INT)� 75,000,000 * (4 + 4) = 600,000,000 B = 572 MB
• (INT, INT, DATETIME,VARCHAR(255), VARCHAR(255))
� 75,000,000 * (4 + 4 + 8 + 256 + 256) =39,600,000,000 bytes = 37 G
• 39,600,000,000 / 600,000,000 = 66
• Mind use case• Mind location
Slow is Relative
9 ©2021 Percona
![Page 18: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/18.jpg)
• Mind your data!• Mind use case
• Popular website• Admin interface• Weekly cron job
• Mind location
Slow is Relative
9 ©2021 Percona
![Page 19: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/19.jpg)
• Mind your data!• Mind use case• Mind location
• Server, used by multiple connections• Dedicated for OLAP queriesSlow is Relative
9 ©2021 Percona
![Page 20: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/20.jpg)
• MySQL performs a job to execute it
• In the worst case scenario it will doa full table scan• CREATE INDEX• ANALYZE TABLE ...
UPDATE HISTOGRAM ON ...
• Incorrect index can be used
Why isthe QuerySlow
10 ©2021 Percona
![Page 21: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/21.jpg)
• MySQL performs a job to execute it• In the worst case scenario it will do
a full table scan• CREATE INDEX• ANALYZE TABLE ...
UPDATE HISTOGRAM ON ...
• Incorrect index can be used
Why isthe QuerySlow
10 ©2021 Percona
![Page 22: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/22.jpg)
• MySQL performs a job to execute it• In the worst case scenario it will do
a full table scan• CREATE INDEX• ANALYZE TABLE ...
UPDATE HISTOGRAM ON ...
• Incorrect index can be used
Why isthe QuerySlow
10 ©2021 Percona
![Page 23: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/23.jpg)
Query sent
Connection Pool:Authentication, Caches;SQL interface; Parser
Optimizer
Storage engines
Hardware
Query ExecutionWorkflow
11 ©2021 Percona
![Page 24: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/24.jpg)
• Selecting a lot of data• SELECT * FROM
many columns table
• Badly written• LEFT JOIN instead of INNER JOIN• Many values in IN()• Retrieving large result set, then
discarding• Not effective SQL
� For particular MySQL version
• We can still improve performance
You May not BeAble to Changea Slow Query
12 ©2021 Percona
![Page 25: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/25.jpg)
• Selecting a lot of data• SELECT * FROM
many columns table
• Badly written• LEFT JOIN instead of INNER JOIN• Many values in IN()• Retrieving large result set, then
discarding• Not effective SQL
� For particular MySQL version
• We can still improve performance
You May not BeAble to Changea Slow Query
12 ©2021 Percona
![Page 26: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/26.jpg)
• Selecting a lot of data• SELECT * FROM
many columns table
• Badly written• LEFT JOIN instead of INNER JOIN• Many values in IN()• Retrieving large result set, then
discarding• Not effective SQL
� For particular MySQL version
• We can still improve performance
You May not BeAble to Changea Slow Query
12 ©2021 Percona
![Page 27: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/27.jpg)
Indexes
![Page 28: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/28.jpg)
IndexesHow Do They Work?
![Page 29: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/29.jpg)
SELECT name FROM users WHERE id=12
1 2 5 6 7 9 12 16 18 21
Full Table Scan
15 ©2021 Percona
![Page 30: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/30.jpg)
SELECT name FROM users WHERE id=12
1 2 5 6 7 9 12 16 18 21
Index Access
16 ©2021 Percona
![Page 31: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/31.jpg)
d001d003d008d009
d003******d009******d008******d009******d001******d003******d009******d008******d009******d001******d008******d008******
MySQL Indexes
- B-Tree Mostly
- LSM Tree
- Fractal Tree
- R-Tree Spatial
- Hash Memory SE
- Engine’s
17 ©2021 Percona
![Page 32: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/32.jpg)
• Single columnCREATE INDEX index name ONthe table(the column)
• Multiple columnsCREATE INDEX index name ONthe table(column1, column2)
How to Createan Index
18 ©2021 Percona
![Page 33: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/33.jpg)
• Single columnALTER TABLE table name ADDINDEX [index name](the column)
• Multiple columnsALTER TABLE table name ADDINDEX [index name] (column1,column2)
How to Createan Index
18 ©2021 Percona
![Page 34: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/34.jpg)
IndexesWhen MySQL Uses Indexes
![Page 35: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/35.jpg)
• WHERE the column = a value
• WHERE the column IN(value1,value2, value3)
• WHERE the column LIKE’value%’
• WHERE the column LIKE ’%value’Conditions
20 ©2021 Percona
![Page 36: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/36.jpg)
• WHERE left part = value1AND right part = value2
• WHERE left part = value1 ORright part = value2
• WHERE right part = value1AND left part = value2
• WHERE right part = value1 ORleft part = value2
Conditions
20 ©2021 Percona
![Page 37: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/37.jpg)
• table1 JOIN table2 ONtable1.column1 =table2.column2
• Same as FROM table1, table2WHERE table1.column1 =table2.column2
Joins
21 ©2021 Percona
![Page 38: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/38.jpg)
• table1 JOIN table2 ONtable1.column1 =table2.column2
• Same as FROM table1, table2WHERE table1.column1 =table2.column2Joins
21 ©2021 Percona
![Page 39: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/39.jpg)
• GROUP BY the column
• GROUP BY left part,right part
• GROUP BY right part, left part• GROUP BY the index, another indexGROUP BY
22 ©2021 Percona
![Page 40: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/40.jpg)
• ORDER BY the column
• ORDER BY left part,right part
• ORDER BY right part, left part• ORDER BY the index, another indexORDER BY
23 ©2021 Percona
![Page 41: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/41.jpg)
5.7 ORDER BY left part DESC,right part ASC
8.0 ORDER BY left part DESC,right part ASC• left part must be descending• right part must be ascending• the index(left part DESC,
right part ASC)
ORDER BY
23 ©2021 Percona
![Page 42: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/42.jpg)
• Deterministic, built-in• Return same value for the same
argument• WHERE the column =
FLOOR(123.45)
• Non-deterministic• Return different values for different
invocations• WHERE the column = RAND() ∗ 100
• Stored functions and UDFs• Indexes are not used
Use generated column indexes
Expressions
24 ©2021 Percona
![Page 43: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/43.jpg)
• Deterministic, built-in• Return same value for the same
argument• WHERE the column =
FLOOR(123.45)
• Non-deterministic• Return different values for different
invocations• WHERE the column = RAND() ∗ 100
• Stored functions and UDFs• Indexes are not used
Use generated column indexes
Expressions
24 ©2021 Percona
![Page 44: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/44.jpg)
• Deterministic, built-in• Return same value for the same
argument• WHERE the column =
FLOOR(123.45)
• Non-deterministic• Return different values for different
invocations• WHERE the column = RAND() ∗ 100
• Stored functions and UDFs• Indexes are not used
Use generated column indexes
Expressions
24 ©2021 Percona
![Page 45: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/45.jpg)
• Identify queries not using indexes• Status variables
mysql> select * from performance_schema.session_status
-> where variable_name in (’Created_tmp_tables’,
-> ’Created_tmp_disk_tables’, ’Select_full_join’,
-> ’Select_full_range_join’, ’Select_range’,
-> ’Select_range_check’, ’Select_scan’,
-> ’Sort_merge_passes’, ’Sort_range’, ’Sort_rows’,
-> ’Sort_scan’) and variable_value > 0;
+------------------------+----------------+
| VARIABLE_NAME | VARIABLE_VALUE |
+------------------------+----------------+
| Select_scan | 2 |
+------------------------+----------------+
1 row in set (0,00 sec)
• Analyze if adding an index will help• Add the index• Test first!
• ADD INDEX is an expensive operationUse pt-online-schema-change
When to AddIndexes?
25 ©2021 Percona
![Page 46: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/46.jpg)
• Identify queries not using indexesmysql> show global status like ’Handler_read%’;
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| Handler_read_first | 31 |
| Handler_read_key | 1909 |
| Handler_read_last | 0 |
| Handler_read_next | 4393 |
| Handler_read_prev | 0 |
| Handler_read_rnd | 0 |
| Handler_read_rnd_next | 1135 |
+-----------------------+-------+
• Analyze if adding an index will help• Add the index• Test first!
• ADD INDEX is an expensive operationUse pt-online-schema-change
When to AddIndexes?
25 ©2021 Percona
![Page 47: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/47.jpg)
• Identify queries not using indexes• PERFORMANCE SCHEMA.EVENTS STATEMENTS *
mysql> select * from events_statements_history_long
-> where sql_text like ’select count(*) from employees join %’\G
*************************** 1. row ****************************
...
ROWS_SENT: 1 SELECT_RANGE_CHECK: 0
ROWS_EXAMINED: 541058 SELECT_SCAN: 1
CREATED_TMP_DISK_TABLES: 0 SORT_MERGE_PASSES: 0
CREATED_TMP_TABLES: 0 SORT_RANGE: 0
SELECT_FULL_JOIN: 0 SORT_ROWS: 0
SELECT_FULL_RANGE_JOIN: 0 SORT_SCAN: 0
SELECT_RANGE: 0 NO_INDEX_USED: 0
• Analyze if adding an index will help• Add the index• Test first!
• ADD INDEX is an expensive operationUse pt-online-schema-change
When to AddIndexes?
25 ©2021 Percona
![Page 48: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/48.jpg)
• Identify queries not using indexes• Slow query log
# Time: 2020-10-11T23:34:03.701871Z
# User@Host: root[root] @ localhost [127.0.0.1] Id: 506
# Query_time: 0.024106 Lock_time: 0.000091
Rows_sent: 1 Rows_examined: 1000
SET timestamp=1602459243;
SELECT c FROM sbtest1 WHERE id=996;
• Analyze if adding an index will help• Add the index• Test first!
• ADD INDEX is an expensive operationUse pt-online-schema-change
When to AddIndexes?
25 ©2021 Percona
![Page 49: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/49.jpg)
• Identify queries not using indexes• QAN in PMM
• Analyze if adding an index will help• Add the index• Test first!
• ADD INDEX is an expensive operationUse pt-online-schema-change
When to AddIndexes?
25 ©2021 Percona
![Page 50: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/50.jpg)
• Identify queries not using indexes• Analyze if adding an index will help
• Add the index• Test first!
• ADD INDEX is an expensive operationUse pt-online-schema-change
When to AddIndexes?
25 ©2021 Percona
![Page 51: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/51.jpg)
• Identify queries not using indexes• Analyze if adding an index will help• Add the index
• Test first!• ADD INDEX is an expensive operation
Use pt-online-schema-change
When to AddIndexes?
25 ©2021 Percona
![Page 52: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/52.jpg)
• Identify queries not using indexes• Analyze if adding an index will help• Add the index• Test first!
• ADD INDEX is an expensive operationUse pt-online-schema-change
When to AddIndexes?
25 ©2021 Percona
![Page 53: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/53.jpg)
IndexesOptimizer Histograms
![Page 54: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/54.jpg)
• Since version 8.0
• Collected and used by the Optimizer• Visible in Information Schema• Affects query execution plan, but
not accessMore details
HistogramStatistics
27 ©2021 Percona
![Page 55: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/55.jpg)
• Since version 8.0• Collected and used by the Optimizer
• Visible in Information Schema• Affects query execution plan, but
not accessMore details
HistogramStatistics
27 ©2021 Percona
![Page 56: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/56.jpg)
• Since version 8.0• Collected and used by the Optimizer• Visible in Information Schema
mysql> select HISTOGRAM from information_schema.column_statistics
-> where table_name=’example’\G
*************************** 1. row ***************************
HISTOGRAM: {"buckets": [[1, 0.6], [2, 0.8], [3, 1.0]],
"data-type": "int", "null-values": 0.0, "collation-id": 8,
"last-updated": "2018-11-07 09:07:19.791470",
"sampling-rate": 1.0, "histogram-type": "singleton",
"number-of-buckets-specified": 3}
1 row in set (0.00 sec)
• Affects query execution plan, butnot accessMore details
HistogramStatistics
27 ©2021 Percona
![Page 57: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/57.jpg)
• Since version 8.0• Collected and used by the Optimizer• Visible in Information Schema• Affects query execution plan, but
not access• SELECT ... FROM a JOIN bvs SELECT ... FROM b JOIN a
More details
HistogramStatistics
27 ©2021 Percona
![Page 58: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/58.jpg)
• Since version 8.0• Collected and used by the Optimizer• Visible in Information Schema• Affects query execution plan, but
not accessMore details
HistogramStatistics
27 ©2021 Percona
![Page 59: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/59.jpg)
1 2 3 4 5 6 7 8 9 100
200
400
600
800
Indexes:Number ofItems with SameValue
28 ©2021 Percona
![Page 60: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/60.jpg)
1 2 3 4 5 6 7 8 9 100
200
400
600
800
Indexes:Cardinality
29 ©2021 Percona
![Page 61: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/61.jpg)
1 2 3 4 5 6 7 8 9 100
200
400
600
800
Histograms:Number ofValues in EachBucket
30 ©2021 Percona
![Page 62: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/62.jpg)
1 2 3 4 5 6 7 8 9 100
0.2
0.4
0.6
0.8
1
Histograms:Data in theHistogram
31 ©2021 Percona
![Page 63: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/63.jpg)
• Data distribution is far from uniform• Query accesses two or more tables• Indexes cannot be used
• Maintaining them is too expensive• They are already used for different
conditionsCreateHistograms
32 ©2021 Percona
![Page 64: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/64.jpg)
Diagnostics
![Page 65: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/65.jpg)
DiagnosticsEXPLAIN: How Optimizer Works
![Page 66: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/66.jpg)
• EXPLAIN• Estimates the query execution plan
5.6- EXTENDED5.6- PARTITIONS
5.6+ FORMAT=JSON8.0+ FORMAT=TREE
• INFORMATION SCHEMA.OPTIMIZER TRACE
• Real data, collected when query wasexecuting
• Advanced topic
How to Findhow MySQLUses Indexes
35 ©2021 Percona
![Page 67: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/67.jpg)
• EXPLAIN• Estimates the query execution plan
5.6- EXTENDED5.6- PARTITIONS
5.6+ FORMAT=JSON8.0+ FORMAT=TREE
• INFORMATION SCHEMA.OPTIMIZER TRACE
• Real data, collected when query wasexecuting
• Advanced topic
How to Findhow MySQLUses Indexes
35 ©2021 Percona
![Page 68: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/68.jpg)
mysql> EXPLAIN SELECT first_name, last_name, title, salary FROM employees
-> JOIN salaries USING(emp_no) JOIN titles USING(emp_no)
-> WHERE salary = (SELECT MAX(salary) FROM salaries
-> JOIN titles WHERE titles.to_date > CURDATE());
+----+-------------+-----------+------------+------+---------------+---------+---------+
| id | select_type | table | partitions | type | possible_keys | key | key_len |
+----+-------------+-----------+------------+------+---------------+---------+---------+
| 1 | PRIMARY | employees | NULL | ALL | PRIMARY | NULL | NULL ...
| 1 | PRIMARY | salaries | NULL | ref | PRIMARY | PRIMARY | 4 ...
| 1 | PRIMARY | titles | NULL | ref | PRIMARY | PRIMARY | 4 ...
| 2 | SUBQUERY | titles | NULL | ALL | NULL | NULL | NULL ...
| 2 | SUBQUERY | salaries | NULL | ALL | NULL | NULL | NULL ...
+----+-------------+-----------+------------+------+---------------+---------+---------+
+----+-...-+----------------------------+---------+----------+-------------------------------+
| id | ... | ref | rows | filtered | Extra |
+----+-...-+----------------------------+---------+----------+-------------------------------+
| 1 | ... | NULL | 299113 | 100.00 | NULL |
| 1 | ... | employees.employees.emp_no | 9 | 10.00 | Using where |
| 1 | ... | employees.employees.emp_no | 1 | 100.00 | Using index |
| 2 | ... | NULL | 442189 | 33.33 | Using where |
| 2 | ... | NULL | 2838426 | 100.00 | Using join buffer (hash join) |
+----+-...-+----------------------------+---------+----------+-------------------------------+
5 rows in set, 1 warning (0,01 sec)
299113 * 9 * 1 * 442189 * 2838426 = 3,378,806,408,204,514,738
EXPLAIN: rows
36 ©2021 Percona
![Page 69: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/69.jpg)
mysql> EXPLAIN SELECT title, MAX(salary) AS maxs FROM employees
-> JOIN salaries USING(emp_no) JOIN titles USING(emp_no)
-> GROUP BY title ORDER BY maxs DESC;
+----+-------------+-----------+------------+-------+---------------+---------+---------+
| id | select_type | table | partitions | type | possible_keys | key | key_len
+----+-------------+-----------+------------+-------+---------------+---------+---------+
| 1 | SIMPLE | employees | NULL | index | PRIMARY | PRIMARY | 4 ...
| 1 | SIMPLE | titles | NULL | ref | PRIMARY,title | PRIMARY | 4 ...
| 1 | SIMPLE | salaries | NULL | ref | PRIMARY | PRIMARY | 4 ...
+----+-------------+-----------+------------+-------+---------------+---------+---------+
EXPLAIN: type
37 ©2021 Percona
![Page 70: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/70.jpg)
ALL Read all rows
index Read all rows from the indexrange Range: N ... M
subquery Subqueriesmerge Combination of two indexes
ref Comparision with single valuefulltext Fulltext index
const Single rowsystem Table has single row
QueryExecution Type
38 ©2021 Percona
![Page 71: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/71.jpg)
ALL Read all rowsindex Read all rows from the index
range Range: N ... Msubquery Subqueries
merge Combination of two indexesref Comparision with single value
fulltext Fulltext indexconst Single row
system Table has single row
QueryExecution Type
38 ©2021 Percona
![Page 72: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/72.jpg)
ALL Read all rowsindex Read all rows from the indexrange Range: N ... M
subquery Subqueriesmerge Combination of two indexes
ref Comparision with single valuefulltext Fulltext index
const Single rowsystem Table has single row
QueryExecution Type
38 ©2021 Percona
![Page 73: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/73.jpg)
ALL Read all rowsindex Read all rows from the indexrange Range: N ... M
subquery Subqueries� index subquery� unique subquery
merge Combination of two indexesref Comparision with single value
fulltext Fulltext indexconst Single row
system Table has single row
QueryExecution Type
38 ©2021 Percona
![Page 74: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/74.jpg)
ALL Read all rowsindex Read all rows from the indexrange Range: N ... M
subquery Subqueriesmerge Combination of two indexes
� index merge
ref Comparision with single valuefulltext Fulltext index
const Single rowsystem Table has single row
QueryExecution Type
38 ©2021 Percona
![Page 75: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/75.jpg)
ALL Read all rowsindex Read all rows from the indexrange Range: N ... M
subquery Subqueriesmerge Combination of two indexes
ref Comparision with single value� ref or null� ref� eq ref
fulltext Fulltext indexconst Single row
system Table has single row
QueryExecution Type
38 ©2021 Percona
![Page 76: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/76.jpg)
ALL Read all rowsindex Read all rows from the indexrange Range: N ... M
subquery Subqueriesmerge Combination of two indexes
ref Comparision with single valuefulltext Fulltext index
const Single rowsystem Table has single row
QueryExecution Type
38 ©2021 Percona
![Page 77: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/77.jpg)
ALL Read all rowsindex Read all rows from the indexrange Range: N ... M
subquery Subqueriesmerge Combination of two indexes
ref Comparision with single valuefulltext Fulltext index
const Single row
system Table has single row
QueryExecution Type
38 ©2021 Percona
![Page 78: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/78.jpg)
ALL Read all rowsindex Read all rows from the indexrange Range: N ... M
subquery Subqueriesmerge Combination of two indexes
ref Comparision with single valuefulltext Fulltext index
const Single rowsystem Table has single row
QueryExecution Type
38 ©2021 Percona
![Page 79: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/79.jpg)
mysql> EXPLAIN SELECT title, MAX(salary) AS maxs FROM employees
-> JOIN salaries USING(emp_no) JOIN titles USING(emp_no)
-> GROUP BY title ORDER BY maxs DESC;
+----+-------------+-----------+------------+-------+---------------+---------+---------+
| id | select_type | table | partitions | type | possible_keys | key | key_len
+----+-------------+-----------+------------+-------+---------------+---------+---------+
| 1 | SIMPLE | employees | NULL | index | PRIMARY | PRIMARY | 4 ...
| 1 | SIMPLE | titles | NULL | ref | PRIMARY,title | PRIMARY | 4 ...
| 1 | SIMPLE | salaries | NULL | ref | PRIMARY | PRIMARY | 4 ...
+----+-------------+-----------+------------+-------+---------------+---------+---------+EXPLAIN:key andpossible keys
39 ©2021 Percona
![Page 80: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/80.jpg)
mysql> EXPLAIN SELECT title, MAX(salary) AS maxs FROM employees
-> JOIN salaries USING(emp_no)
-> JOIN titles USING(emp_no)
-> GROUP BY title ORDER BY maxs DESC;
+----+-------------+-----------+------------+-------+---------------+---------+---------+
| id | select_type | table | partitions | type | possible_keys | key | key_len
+----+-------------+-----------+------------+-------+---------------+---------+---------+
| 1 | SIMPLE | employees | NULL | index | PRIMARY | PRIMARY | 4 ...
| 1 | SIMPLE | titles | NULL | ref | PRIMARY,title | PRIMARY | 4 ...
| 1 | SIMPLE | salaries | NULL | ref | PRIMARY | PRIMARY | 4 ...
+----+-------------+-----------+------------+-------+---------------+---------+---------+EXPLAIN:JOIN order
40 ©2021 Percona
![Page 81: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/81.jpg)
mysql> EXPLAIN SELECT first_name, last_name, title, salary FROM employees
-> JOIN salaries USING(emp_no) JOIN titles USING(emp_no)
-> WHERE salary IN (SELECT MAX(salary) FROM salaries
-> JOIN titles WHERE titles.to_date > CURDATE());
...
5 rows in set, 1 warning (0,01 sec)
mysql> SHOW WARNINGS\G
*************************** 1. row ***************************
Level: Note
Code: 1003
Message: /* select#1 */ select ‘employees‘.‘employees‘.‘first_name‘ AS ‘first_name‘,
‘employees‘.‘employees‘.‘last_name‘ AS ‘last_name‘,‘employees‘.‘salaries‘.‘salary‘ AS ‘salary‘
from ‘employees‘.‘employees‘ join ‘employees‘.‘salaries‘
where ((‘employees‘.‘salaries‘.‘emp_no‘ = ‘employees‘.‘employees‘.‘emp_no‘)
and <in_optimizer>(‘employees‘.‘salaries‘.‘salary‘,‘employees‘.‘salaries‘.‘salary‘ in
( <materialize> (/* select#2 */
select max(‘employees‘.‘salaries‘.‘salary‘)
from ‘employees‘.‘salaries‘ join ‘employees‘.‘titles‘
where (‘employees‘.‘titles‘.‘to_date‘ > <cache>(curdate())) having true ),
<primary_index_lookup>(‘employees‘.‘salaries‘.‘salary‘ in
<temporary table> on <auto_distinct_key>
where ((‘employees‘.‘salaries‘.‘salary‘ = ‘<materialized_subquery>‘.‘MAX(salary)‘))))))
1 row in set (0,00 sec)
Actual Query
41 ©2021 Percona
![Page 82: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/82.jpg)
mysql> explain select * from t1\G
*************************** 1. row ***************************
...
rows: 12
Extra: NULL
mysql> explain select * from t1 where f2=12\G
*************************** 1. row ***************************
...
key: NULL
...
rows: 12
Extra: Using where
Effect ofIndexes: Before
42 ©2021 Percona
![Page 83: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/83.jpg)
mysql> alter table t1 add index(f2);
Query OK, 12 rows affected (0.07 sec)
Records: 12 Duplicates: 0 Warnings: 0
mysql> explain select * from t1 where f2=12\G
*************************** 1. row ***************************
...
key: f2
key_len: 5
ref: const
rows: 1
Extra: NULL
1 row in set (0.00 sec)
Effect ofIndexes: After
43 ©2021 Percona
![Page 84: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/84.jpg)
DiagnosticsReal Numbers: Inside Storage Engine
![Page 85: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/85.jpg)
• EXPLAIN is optimisticmysql> explain select * from ol
-> where thread_id=10432 and site_id != 9939
-> order by id limit 3\G
*************************** 1. row ***************************
id: 1 | ref: NULL
select_type: SIMPLE | rows: 33
table: ol | filtered: 8.07
partitions: NULL | Extra: Using where
type: index
possible_keys: thread_id
key: PRIMARY
key_len: 4
1 row in set, 1 warning (0,00 sec)
• ’Handler *’ show truthmysql> FLUSH STATUS;
mysql> select * from ol
-> where thread_id=10432 and site_id != 9939
-> order by id limit 3;
mysql> show status like ’Handler%’;
+----------------------------+--------+
| Variable_name | Value |
+----------------------------+--------+
...
| Handler_read_first | 1 |
| Handler_read_key | 1 |
| Handler_read_last | 0 |
| Handler_read_next | 100000 |
...
Handler *Status Variables
45 ©2021 Percona
![Page 86: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/86.jpg)
• ’Handler *’ show truthmysql> FLUSH STATUS;
mysql> select * from ol
-> where thread_id=10432 and site_id != 9939
-> order by id limit 3;
mysql> show status like ’Handler%’;
+----------------------------+--------+
| Variable_name | Value |
+----------------------------+--------+
...
| Handler_read_first | 1 |
| Handler_read_key | 1 |
| Handler_read_last | 0 |
| Handler_read_next | 100000 |
...
Handler *Status Variables
45 ©2021 Percona
![Page 87: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/87.jpg)
DiagnosticsReal Numbers: Inside the Server
![Page 88: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/88.jpg)
• SHOW [FULL] PROCESSLIST
• INFORMATION SCHEMA.PROCESSLIST
• performance schema.THREADS
• Your first alert of performance issue• Shows all running queries
PROCESSLIST
47 ©2021 Percona
![Page 89: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/89.jpg)
• SHOW [FULL] PROCESSLIST
• INFORMATION SCHEMA.PROCESSLIST
• performance schema.THREADS
• Your first alert of performance issue
• Shows all running queries
PROCESSLIST
47 ©2021 Percona
![Page 90: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/90.jpg)
• SHOW [FULL] PROCESSLIST
• INFORMATION SCHEMA.PROCESSLIST
• performance schema.THREADS
• Your first alert of performance issue• Shows all running queriesPROCESSLIST
47 ©2021 Percona
![Page 91: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/91.jpg)
• Can be seen in the PROCESSLISTmysql> show processlist\G
************************ 1. row ************************
Id: 7
User: root
Host: localhost:48799
db: employees
Command: Query
Time: 2
State: Sending data
Info: select count(*) from employees
join titles using(emp_no)
where title=’Senior Engineer’
...
• PERFORMANCE SCHEMA.EVENTS STAGES *
ExecutionStages
48 ©2021 Percona
![Page 92: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/92.jpg)
• Can be seen in the PROCESSLIST• Very useful when you need to answer
on the question: ”What is my serverdoing now?”
• PERFORMANCE SCHEMA.EVENTS STAGES *
ExecutionStages
48 ©2021 Percona
![Page 93: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/93.jpg)
• PERFORMANCE SCHEMA.EVENTS STAGES *mysql> select eshl.event_name, substr(sql_text, 1, 15) ‘sql‘,
-> eshl.timer_wait/1000000000000 w_s
-> from events_stages_history_long
-> eshl join events_statements_history_long esthl on
-> (eshl.nesting_event_id = esthl.event_id) where
-> esthl.current_schema=’employees’ and sql_text like
-> ’select count(*) from employees%’
-> order by eshl.timer_start asc;
+--------------------------------+-----------------+--------+
| event_name | sql | w_s |
+--------------------------------+-----------------+--------+
| stage/sql/starting | select count(*) | 0.0002 |
| stage/sql/checking permissions | select count(*) | 0.0000 |
...
ExecutionStages
48 ©2021 Percona
![Page 94: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/94.jpg)
• PERFORMANCE SCHEMA.EVENTS STAGES *...
| stage/sql/checking permissions | select count(*) | 0.0000 |
| stage/sql/Opening tables | select count(*) | 0.0000 |
| stage/sql/init | select count(*) | 0.0001 |
| stage/sql/System lock | select count(*) | 0.0000 |
| stage/sql/optimizing | select count(*) | 0.0000 |
| stage/sql/statistics | select count(*) | 0.0001 |
| stage/sql/preparing | select count(*) | 0.0000 |
| stage/sql/executing | select count(*) | 0.0000 |
| stage/sql/Sending data | select count(*) | 5.4915 |
| stage/sql/end | select count(*) | 0.0000 |
...
ExecutionStages
48 ©2021 Percona
![Page 95: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/95.jpg)
• Status variablesmysql> flush status;
Query OK, 0 rows affected (0,01 sec)
mysql> select count(*) from employees join titles using(emp_no)
-> where title=’Senior Engineer’;
+----------+
| count(*) |
+----------+
| 97750 |
+----------+
1 row in set (5,44 sec)
• sys.statement analysis
TemporaryTablesandOther Job
49 ©2021 Percona
![Page 96: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/96.jpg)
• Status variablesmysql> select * from performance_schema.session_status
-> where variable_name in (’Created_tmp_tables’,
-> ’Created_tmp_disk_tables’, ’Select_full_join’,
-> ’Select_full_range_join’, ’Select_range’,
-> ’Select_range_check’, ’Select_scan’, ’Sort_merge_passes’,
-> ’Sort_range’, ’Sort_rows’, ’Sort_scan’)
-> and variable_value > 0;
+------------------------+----------------+
| VARIABLE_NAME | VARIABLE_VALUE |
+------------------------+----------------+
| Select_scan | 2 |
+------------------------+----------------+
1 row in set (0,00 sec)
• sys.statement analysis
TemporaryTablesandOther Job
49 ©2021 Percona
![Page 97: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/97.jpg)
• PERFORMANCE SCHEMA.EVENTS STATEMENTS *mysql> select * from events_statements_history_long
-> where sql_text like
-> ’select count(*) from employees join %’\G
*************************** 1. row ****************************
...
ROWS_SENT: 1 SELECT_RANGE_CHECK: 0
ROWS_EXAMINED: 541058 SELECT_SCAN: 1
CREATED_TMP_DISK_TABLES: 0 SORT_MERGE_PASSES: 0
CREATED_TMP_TABLES: 0 SORT_RANGE: 0
SELECT_FULL_JOIN: 0 SORT_ROWS: 0
SELECT_FULL_RANGE_JOIN: 0 SORT_SCAN: 0
SELECT_RANGE: 0 NO_INDEX_USED: 0
• sys.statement analysis
TemporaryTablesandOther Job
49 ©2021 Percona
![Page 98: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/98.jpg)
• sys.statement analysismysql> select * from statement_analysis where query like
-> ’SELECT COUNT ( * ) FROM ‘emplo%’ and db=’employees’\G
*************************** 1. row ***************************
query: SELECT COUNT ( * ) FROM ‘emplo ... ‘emp_no‘ ) WHE...
db: employees max_latency: 5.59 s
full_scan: avg_latency: 5.41 s
exec_count: 7 lock_latency: 2.24 ms
err_count: 0 rows_sent: 7
warn_count: 0 rows_sent_avg: 1
total_latency: 37.89 s rows_examined: 3787406
TemporaryTablesandOther Job
49 ©2021 Percona
![Page 99: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/99.jpg)
• sys.statement analysisrows_examined_avg: 541058
rows_affected: 0
rows_affected_avg: 0
tmp_tables: 0
tmp_disk_tables: 0
rows_sorted: 0
sort_merge_passes: 0
digest: 4086bc3dc6510a1d9c8f2fe1f59f0943
first_seen: 2016-04-14 15:19:19
last_seen: 2016-04-14 16:13:14
TemporaryTablesandOther Job
49 ©2021 Percona
![Page 100: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/100.jpg)
How to Affect QueryPlans
![Page 101: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/101.jpg)
• Index statistics• Histogram statistics• Optimizer switches• Bugs in optimizerWhat has an
Effect on QueryOptimizerPlans?
51 ©2021 Percona
![Page 102: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/102.jpg)
• Collected by storage engine
Index Statistics
52 ©2021 Percona
![Page 103: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/103.jpg)
• Collected by storage engine• Used by Optimizer
Index Statistics
52 ©2021 Percona
![Page 104: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/104.jpg)
• Can be examined by SHOW INDEXmysql> show index from sbtest1;
+---------+----------+-------------+-------------+
| Table | Key_name | Column_name | Cardinality |
+---------+----------+-------------+-------------+
| sbtest1 | k_1 | k | 49142 |
+---------+----------+-------------+-------------+
mysql> select count(distinct id),
-> count(distinct k) from sbtest1;
+--------------------+-------------------+
| count(distinct id) | count(distinct k) |
+--------------------+-------------------+
| 100000 | 17598 |
+--------------------+-------------------+
Index Statistics
52 ©2021 Percona
![Page 105: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/105.jpg)
• Can be updated• ANALYZE TABLE• If does not help: rebuild the table
� OPTIMIZE TABLE� ALTER TABLE ENGINE=INNODB; ANALYZE TABLE
Index Statistics
52 ©2021 Percona
![Page 106: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/106.jpg)
• Since version 8.0
• Collected and used by the Optimizer• Visible in Information Schema
More details
HistogramStatistics
53 ©2021 Percona
![Page 107: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/107.jpg)
• Since version 8.0• Collected and used by the Optimizer
• Visible in Information SchemaMore details
HistogramStatistics
53 ©2021 Percona
![Page 108: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/108.jpg)
• Since version 8.0• Collected and used by the Optimizer• Visible in Information Schema
mysql> select HISTOGRAM from information_schema.column_statistics
-> where table_name=’example’\G
*************************** 1. row ***************************
HISTOGRAM: {"buckets": [[1, 0.6], [2, 0.8], [3, 1.0]],
"data-type": "int", "null-values": 0.0, "collation-id": 8,
"last-updated": "2018-11-07 09:07:19.791470",
"sampling-rate": 1.0, "histogram-type": "singleton",
"number-of-buckets-specified": 3}
1 row in set (0.00 sec)
More details
HistogramStatistics
53 ©2021 Percona
![Page 109: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/109.jpg)
• Since version 8.0• Collected and used by the Optimizer• Visible in Information Schema
More detailsHistogramStatistics
53 ©2021 Percona
![Page 110: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/110.jpg)
mysql> select @@optimizer_switch\G
*************************** 1. row ***************************
@@optimizer_switch: index_merge=on,index_merge_union=on,
index_merge_sort_union=on,index_merge_intersection=on,
engine_condition_pushdown=on,index_condition_pushdown=on,
mrr=on,mrr_cost_based=on,
block_nested_loop=on,batched_key_access=off,
materialization=on,semijoin=on,loosescan=on,firstmatch=on,
duplicateweedout=on,subquery_materialization_cost_based=on,
use_index_extensions=on,condition_fanout_filter=on,
derived_merge=on
1 row in set (0,00 sec)
• Turn ON and OFF particularoptimization
• Can be unhelpful• Work with them as with any other
option
• If helps implement in queriesSELECT /*+ SEMIJOIN(FIRSTMATCH, LOOSESCAN) */ * FROM t1 ...;
SELECT /*+ BKA(t1) NO_BKA(t2) */ * FROM t1 INNER JOIN t2 WHERE ...;
OptimizerSwitches
54 ©2021 Percona
![Page 111: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/111.jpg)
• Turn ON and OFF particularoptimization
• Can be unhelpful• Work with them as with any other
option
• If helps implement in queriesSELECT /*+ SEMIJOIN(FIRSTMATCH, LOOSESCAN) */ * FROM t1 ...;
SELECT /*+ BKA(t1) NO_BKA(t2) */ * FROM t1 INNER JOIN t2 WHERE ...;
OptimizerSwitches
54 ©2021 Percona
![Page 112: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/112.jpg)
• Turn ON and OFF particularoptimization
• Can be unhelpful• Especially for queries, tuned for
previous versions
• Work with them as with any otheroption
• If helps implement in queriesSELECT /*+ SEMIJOIN(FIRSTMATCH, LOOSESCAN) */ * FROM t1 ...;
SELECT /*+ BKA(t1) NO_BKA(t2) */ * FROM t1 INNER JOIN t2 WHERE ...;
OptimizerSwitches
54 ©2021 Percona
![Page 113: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/113.jpg)
• Turn ON and OFF particularoptimization
• Can be unhelpful• Work with them as with any other
option• Turn OFF and try
SET optimizer_switch = ’use_index_extensions=off’;
SELECT ...
EXPLAIN SELECT ...
• If helps implement in queriesSELECT /*+ SEMIJOIN(FIRSTMATCH, LOOSESCAN) */ * FROM t1 ...;
SELECT /*+ BKA(t1) NO_BKA(t2) */ * FROM t1 INNER JOIN t2 WHERE ...;
OptimizerSwitches
54 ©2021 Percona
![Page 114: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/114.jpg)
• Turn ON and OFF particularoptimization
• Can be unhelpful• Work with them as with any other
option• If helps implement in queries
SELECT /*+ SEMIJOIN(FIRSTMATCH, LOOSESCAN) */ * FROM t1 ...;
SELECT /*+ BKA(t1) NO_BKA(t2) */ * FROM t1 INNER JOIN t2 WHERE ...;
OptimizerSwitches
54 ©2021 Percona
![Page 115: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/115.jpg)
• Optimizer choses wrong plan for noreason
• Statistics are up to date• Histograms are not usable• Solution• On every upgrade
• Remove index hints• Test if the query improved• You must do it even for minor
version upgrades!
Bugs inOptimizer
55 ©2021 Percona
![Page 116: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/116.jpg)
• Optimizer choses wrong plan for noreason
• Statistics are up to date• Histograms are not usable
• Solution• On every upgrade
• Remove index hints• Test if the query improved• You must do it even for minor
version upgrades!
Bugs inOptimizer
55 ©2021 Percona
![Page 117: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/117.jpg)
• Optimizer choses wrong plan for noreason
• Statistics are up to date• Histograms are not usable• Solution
• Use index hints� FORCE INDEX� IGNORE INDEX
• On every upgrade• Remove index hints• Test if the query improved• You must do it even for minor
version upgrades!
Bugs inOptimizer
55 ©2021 Percona
![Page 118: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/118.jpg)
• Optimizer choses wrong plan for noreason
• Statistics are up to date• Histograms are not usable• Solution• On every upgrade
• Remove index hints• Test if the query improved• You must do it even for minor
version upgrades!
Bugs inOptimizer
55 ©2021 Percona
![Page 119: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/119.jpg)
• EXPLAIN is essential for query tuning• Real job is done by storage engine• Index statistics affect query
execution plan• All index hints, optimizer hints and
other workarounds must be validatedon each upgrade
Summary
56 ©2021 Percona
![Page 120: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/120.jpg)
EXPLAIN Syntax
EXPLAIN FORMAT=JSON is Cool!
Troubleshooting add-ons
Optimizer Statistics aka Histograms
Optimizer Hints
Tracing the Optimizer
MoreInformation
57 ©2021 Percona
![Page 121: MySQL Query Tuning](https://reader033.fdocuments.net/reader033/viewer/2022041912/625509db885b3967f7002887/html5/thumbnails/121.jpg)
www.slideshare.net/SvetaSmirnova
twitter.com/svetsmirnova
github.com/svetasmirnovaThank you!
58 ©2021 Percona