SlideShare a Scribd company logo
EXPLAIN FORMAT=JSON
Why to use?
April, 19, 2016
Sveta Smirnova
•The appearance
•Innovations
•Grouping and ordering
•Subqueries and unions
•Troubleshooting sugar
Table of Contents
2
• Has nice structured view
• Easily machine-readable
• Allows MySQL Workbench draw nice
graphs
EXPLAIN FORMAT=JSON was introduced in 5.6
3
• It has more information than regular
EXPLAIN
• Can replace OPTIMIZER TRACE for some
cases
Trendy? - Not only!
4
Innovations
5
• According to user manual
• The percentage of rows that were actually
needed, against the equal or bigger number
of resolved rows.
• Is this good or bad?
What number of ”filtered” rows mean?
6
• According to user manual
• Example query
mysql> select * from Country where Name=’Russian Federation’G
*************************** 1. row ***************************
Code: RUS
Name: Russian Federation
Continent: Europe
...
HeadOfState: Vladimir Putin
Capital: 3580
Code2: RU
1 row in set (0.00 sec)
What number of ”filtered” rows mean?
6
• According to user manual
• Example query
• Regular EXPLAIN
mysql> explain select * from Country where Name=’Russian Federation’;
+-----+------+----------+-------------+
| ... | rows | filtered | Extra |
+-----+------+----------+-------------+
| ... | 239 | 10.00 | Using where |
+-----+------+----------+-------------+
• What happened with rows?
• Why they were filtered?
What number of ”filtered” rows mean?
6
• According to user manual
• Example query
• Regular EXPLAIN
• EXPLAIN FORMAT=JSON has the answer
"table": {
"table_name": "Country",
"access_type": "ALL",
"rows_examined_per_scan": 239,
"rows_produced_per_join": 23,
"filtered": "10.00",
What number of ”filtered” rows mean?
6
• Covered indexes
• Usually use more than one column
• Contain all fields, necessary to resolve the
query
When to use covered indexes?
7
• Covered indexes
• Example
mysql> select count(*) from Country
-> where Continent=’Africa’ and Population > 1000000;
+----------+
| count(*) |
+----------+
| 47 |
+----------+
1 row in set (0,00 sec)
• Will the query use Primary Key?
• Or * will look through all rows?
When to use covered indexes?
7
• Covered indexes
• Example
• EXPLAIN FORMAT=JSON has the answer
mysql> explain format=json select count(*) from Country
-> where Continent=’Africa’ and Population > 1000000G
*************************** 1. row ***************************
...
"used_columns": [
"Continent",
"Population"
],
...
When to use covered indexes?
7
• Covered indexes
• Example
• EXPLAIN FORMAT=JSON has the answer
• We only need Continent and Population
columns for the index
When to use covered indexes?
7
• Example queries
SELECT first_name, last_name FROM employees WHERE
first_name=’Steve’;
...first_name=’Steve’ and last_name like ’V%’;
...first_name=’Steve’ and last_name like ’V%’ and hire_date>’1990-01-01’;
Which part of index used?
8
• Example queries
• Candidate indexes
CREATE INDEX comp1(first_name);
CREATE INDEX comp2(first_name, last_name);
CREATE INDEX comp3(first_name, last_name, hire_date);
• Last one seem to fit all the queries
Which part of index used?
8
• Example queries
• Candidate indexes
• Index effectiveness
mysql> explain format=json SELECT first_name, last_name FROM employees
-> WHERE first_name=’Steve’ and last_name like ’V%’
-> and hire_date > ’1990-01-01’G
*************************** 1. row ***************************
EXPLAIN: {
...
"used_key_parts": [
"first_name",
"last_name"
],
Which part of index used?
8
• Example queries
• Candidate indexes
• Index effectiveness
• Column hire date is not used!
• Most effective index would be on
(first name, last name)
Which part of index used?
8
• Use case
• Table has two or more indexes
• All can be used to resolve the query
• But only one is chosen
• Why?
Why index chosen?
9
• Use case
• Example
• Table ‘titles‘ in ‘employees‘ database
• The query:
select distinct title from titles where year(from_date) > ’1990’;
• Two indexes:
PRIMARY KEY (‘emp no‘,‘title‘,‘from date‘)
KEY ‘emp no‘ (‘emp no‘)
Why index chosen?
9
• Use case
• Example
• Index emp no has been chosen
mysql> explain select distinct title from titles
-> where year(from_date) > ’1990’G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: titles
partitions: NULL
type: index
possible_keys: PRIMARY,emp_no
key: emp_no
Why index chosen?
9
• Use case
• Example
• Index emp no has been chosen
• The reason
• Cost statistics for emp no
mysql> explain format=json select distinct title
-> from titles where year(from_date) > ’1990’G
...
"cost_info": {
"query_cost": "89796.80"
},
...
Why index chosen?
9
• Use case
• Example
• Index emp no has been chosen
• The reason
"duplicates_removal": {
...
"cost_info": {
"read_cost": "1252.00",
"eval_cost": "88544.80",
"prefix_cost": "89796.80",
"data_read_per_join": "27M"
},
Why index chosen?
9
• Use case
• Example
• Index emp no has been chosen
• The reason
• Cost statistics for PRIMARY KEY
mysql> explain format=json select distinct title from titles
-> force index(primary) where year(from_date) > ’1990’G
...
"cost_info": {
"query_cost": "531269.80"
},
...
Why index chosen?
9
• Use case
• Example
• Index emp no has been chosen
• The reason
• Access by PRIMARY KEY is 531269.80 /
89796.80 = 6 times more expensive!
Why index chosen?
9
Grouping and ordering
10
• Hierarchical structure
"grouping_operation": {
"using_filesort": false,
"table": {
...
How GROUP BY proceed
11
• Hierarchical structure
• Allows to distinguish operations
"grouping_operation": {
"using_temporary_table": true,
"using_filesort": true,
"cost_info": {
"sort_cost": "26.41"
},
"nested_loop": [
{
...
How GROUP BY proceed
11
• Hierarchical structure
• Allows to distinguish operations
• Separate member for DISTINCT
"duplicates_removal": {
"using_temporary_table": true,
"using_filesort": false,
"grouping_operation": {
"using_temporary_table": true,
"using_filesort": true,
...
How GROUP BY proceed
11
• Clearly shows which job required
• Is temporary table for ORDER BY?
mysql> explain select distinct last_name
-> from employees order by last_name ascG
*************************** 1. row ***************************
...
type: ALL
...
rows: 299379
filtered: 100.00
Extra: Using temporary; Using filesort
1 row in set, 1 warning (0.00 sec)
Ordering operations
12
• Clearly shows which job required
• Is temporary table for ORDER BY?
• Lets check what really happened:
mysql> explain format=json select distinct last_name
-> from employees order by last_name ascG
...
"ordering_operation": {
"using_filesort": false, - No temporary table here!
"duplicates_removal": {
"using_temporary_table": true,
"using_filesort": true,
...
Ordering operations
12
• Clearly shows which job required
• Is temporary table for ORDER BY?
• Lets check what really happened:
• Confirmation
mysql> explain format=json select last_name
-> from employees order by last_name ascG
...
"ordering_operation": {
"using_filesort": true,
"cost_info": {
"sort_cost": "299379.00"
...
Ordering operations
12
Subqueries and unions
13
• attached subqueries
• Subqueries which are not converted to JOIN
mysql> explain format=json select emp_no from salaries
-> where salary > (select avg(salary) from salaries)G
*************************** 1. row ***************************
...
"attached_subqueries": [
{
"dependent": false,
"cacheable": true,
"query_block": {
"select_id": 2,
...
Everything about subqueries
14
• attached subqueries
• optimized away subqueries
• Subqueries that were executed only once and
were replaced by their result.
mysql> explain format=json select emp_no, salary from salaries
-> order by (select max(salary) from salaries)G
...
"optimized_away_subqueries": [
{
"dependent": false,
"cacheable": true,
...
Everything about subqueries
14
• attached subqueries
• optimized away subqueries
• Compare with regular EXPLAIN
mysql> explain select emp_no, salary from salaries
-> order by (select max(salary) from salaries)G
...
*************************** 2. row ***************************
id: 2 | key: NULL
select_type: SUBQUERY | key_len: NULL
table: salaries | ref: NULL
partitions: NULL | rows: 2838525
type: ALL | filtered: 100.00
possible_keys: NULL | Extra: NULL
Everything about subqueries
14
• attached subqueries
• optimized away subqueries
• materialized from subquery
• Materialized subquery
mysql> explain format=json select dept_name from departments where
-> dept_no in (select dept_no from dept_manager
-> where to_date is not null)G
...
"table": { | "materialized_from_subquery": {
"table_name": "<subquery2>",| "using_temporary_table": true,
"access_type": "eq_ref", | "query_block": {
...
Everything about subqueries
14
• order by subqueries
• group by subqueries
• having subqueries
• Dependent or not
• Cacheable or not
• If was optimized away
• Information about nested subqueries
Subqueries and GROUP/ORDER BY
15
• All members in parent object union result
• Each query exists in query specifications
array
mysql> explain format=json select Name from City
-> union select Capital from CountryG
*************************** 1. row ***************************
EXPLAIN: { | "table": {
"query_block": { | "table_name": "City",
"union_result": { | ...
... | "table": {
"query_specifications": [ | "table_name": "Country",
{
...
UNION details
16
Troubleshooting sugar
17
• The issue: temporary table
• SQL BUFFER RESULT always uses it
• But how to ensure if original query does not?
mysql> explain select sql_buffer_result emp_no, salary/avg(salary)
-> from salaries group by emp_no, salaryG
*************************** 1. row ***************************
id: 1 | key_len: NULL
select_type: SIMPLE | ref: NULL
table: salaries | rows: 2557022
partitions: NULL | filtered: 100.00
type: ALL | Extra: Using temporary; Using filesort
possible_keys: NULL
key: NULL
SQL BUFFER RESULT is not hidden
18
• The issue: temporary table
• EXPLAIN FORMAT=JSON distinguish
buffer and original query
mysql> explain format=json select sql_buffer_result emp_no,
-> salary/avg(salary) from salaries group by emp_no, salaryG
...
"grouping_operation": {
"using_temporary_table": true,
"using_filesort": true,
...
"buffer_result": {
"using_temporary_table": true,
...
SQL BUFFER RESULT is not hidden
18
• Issue: complicated queries
• Regular EXPLAIN lists tables in rows
mysql> explain select * from employees join dept_manager using
(emp_no) where emp_no in (select emp_no from (select ...
*************************** 1. row ***************************
table: <subquery2>
*************************** 2. row ***************************
table: dept_manager
*************************** 3. row ***************************
table: employees
*************************** 4. row ***************************
table: <derived3>
...
nested loop and JOIN hierarchy
19
• Issue: complicated queries
• Solution: hierarchical structure
mysql> explain format=json select * from employees join dept_manager
-> using (emp_no) where emp_no in (select emp_no...
...
"nested_loop": [
{
"table": { "table_name": "<subquery2>",
...
"nested_loop": [ { "table": { "table_name": "titles",
...
{
"table": { "table_name": "dept_manager", ...
nested loop and JOIN hierarchy
19
• Provides more details than regular
EXPLAIN
• However only necessary information for
DBA
• Elegant way to show it
• Machine-readable
• Trace details in easy-to-view format
EXPLAIN FORMAT=JSON is Cool!
20
• EXPLAIN in the official user manual
• EXPLAIN FORMAT=JSON is Cool! series
More information
21
???
Place for your questions
22
http://www.slideshare.net/SvetaSmirnova
https://twitter.com/svetsmirnova
Thank you!
23

More Related Content

PDF
JSON WEB TOKEN
PDF
Upgrade to MySQL 8.0!
PDF
MySQL Parallel Replication: All the 5.7 and 8.0 Details (LOGICAL_CLOCK)
PDF
Upgrade from MySQL 5.7 to MySQL 8.0
PDF
Redo log improvements MYSQL 8.0
PDF
MySQL Ecosystem in 2023 - FOSSASIA'23 - Alkin.pptx.pdf
PDF
MySQL Database Architectures - InnoDB ReplicaSet & Cluster
PDF
MySQL Administrator 2021 - 네오클로바
JSON WEB TOKEN
Upgrade to MySQL 8.0!
MySQL Parallel Replication: All the 5.7 and 8.0 Details (LOGICAL_CLOCK)
Upgrade from MySQL 5.7 to MySQL 8.0
Redo log improvements MYSQL 8.0
MySQL Ecosystem in 2023 - FOSSASIA'23 - Alkin.pptx.pdf
MySQL Database Architectures - InnoDB ReplicaSet & Cluster
MySQL Administrator 2021 - 네오클로바

What's hot (20)

PDF
InnoDb Vs NDB Cluster
PDF
InnoDB Internal
PDF
Oracle Latch and Mutex Contention Troubleshooting
PDF
mysql 8.0 architecture and enhancement
PDF
MySQL 상태 메시지 분석 및 활용
PDF
MySQL Advanced Administrator 2021 - 네오클로바
PPTX
MongoDB at Scale
PPTX
Query logging with proxysql
PDF
DB Time, Average Active Sessions, and ASH Math - Oracle performance fundamentals
PPTX
Oracle sql high performance tuning
PDF
[pgday.Seoul 2022] PostgreSQL with Google Cloud
PDF
Average Active Sessions RMOUG2007
PDF
What is new in PostgreSQL 14?
PDF
MySQL Performance Tuning: Top 10 Tips
PPTX
Caching solutions with Redis
PDF
MySQL Scalability and Reliability for Replicated Environment
PDF
MySQL/MariaDB Proxy Software Test
PPTX
MongoDB Atlas
PDF
MySQL Security
PPTX
Introduction to MongoDB
InnoDb Vs NDB Cluster
InnoDB Internal
Oracle Latch and Mutex Contention Troubleshooting
mysql 8.0 architecture and enhancement
MySQL 상태 메시지 분석 및 활용
MySQL Advanced Administrator 2021 - 네오클로바
MongoDB at Scale
Query logging with proxysql
DB Time, Average Active Sessions, and ASH Math - Oracle performance fundamentals
Oracle sql high performance tuning
[pgday.Seoul 2022] PostgreSQL with Google Cloud
Average Active Sessions RMOUG2007
What is new in PostgreSQL 14?
MySQL Performance Tuning: Top 10 Tips
Caching solutions with Redis
MySQL Scalability and Reliability for Replicated Environment
MySQL/MariaDB Proxy Software Test
MongoDB Atlas
MySQL Security
Introduction to MongoDB
Ad

Viewers also liked (12)

PDF
Using Apache Spark and MySQL for Data Analysis
PDF
Performance Schema for MySQL Troubleshooting
PDF
WiredTiger In-Memory vs WiredTiger B-Tree
PDF
Эффективная отладка репликации MySQL
PDF
Preparse Query Rewrite Plugins
PDF
Open Source SQL databases enters millions queries per second era
PDF
Жизнь, удивительные приключения и смерть бага MySQL
PDF
OpenSource SQL Databases Enter Millions Queries per Second Era
PDF
New features in Performance Schema 5.7 in action
PDF
Отладка производительности СУБД MySQL
PDF
MySQL Replication Troubleshooting for Oracle DBAs
PDF
Mysql Explain Explained
Using Apache Spark and MySQL for Data Analysis
Performance Schema for MySQL Troubleshooting
WiredTiger In-Memory vs WiredTiger B-Tree
Эффективная отладка репликации MySQL
Preparse Query Rewrite Plugins
Open Source SQL databases enters millions queries per second era
Жизнь, удивительные приключения и смерть бага MySQL
OpenSource SQL Databases Enter Millions Queries per Second Era
New features in Performance Schema 5.7 in action
Отладка производительности СУБД MySQL
MySQL Replication Troubleshooting for Oracle DBAs
Mysql Explain Explained
Ad

Similar to Why Use EXPLAIN FORMAT=JSON? (20)

PDF
Introduction into MySQL Query Tuning
PDF
Query Optimization with MySQL 5.6: Old and New Tricks
PDF
Introduction to MySQL Query Tuning for Dev[Op]s
PDF
Troubleshooting MySQL Performance
PDF
Quick Wins
PPTX
MYSQL single rowfunc-multirowfunc-groupby-having
PDF
Scaling MySQL Strategies for Developers
PDF
MySQL Query tuning 101
PDF
MySQL Indexing : Improving Query Performance Using Index (Covering Index)
PDF
2018 db-rainer schuettengruber-beating-oracles_optimizer_at_its_own_game-pres...
PDF
Performance Schema for MySQL Troubleshooting
PDF
MySQL 5.7 in a Nutshell
PDF
Covering indexes
PDF
MYSQL Query Anti-Patterns That Can Be Moved to Sphinx
PDF
Webinar 2013 advanced_query_tuning
PDF
Query optimizer vivek sharma
PDF
MySQL Query And Index Tuning
PDF
56 Query Optimization
PDF
Performance Schema for MySQL Troubleshooting
PPTX
MySQL performance tuning
Introduction into MySQL Query Tuning
Query Optimization with MySQL 5.6: Old and New Tricks
Introduction to MySQL Query Tuning for Dev[Op]s
Troubleshooting MySQL Performance
Quick Wins
MYSQL single rowfunc-multirowfunc-groupby-having
Scaling MySQL Strategies for Developers
MySQL Query tuning 101
MySQL Indexing : Improving Query Performance Using Index (Covering Index)
2018 db-rainer schuettengruber-beating-oracles_optimizer_at_its_own_game-pres...
Performance Schema for MySQL Troubleshooting
MySQL 5.7 in a Nutshell
Covering indexes
MYSQL Query Anti-Patterns That Can Be Moved to Sphinx
Webinar 2013 advanced_query_tuning
Query optimizer vivek sharma
MySQL Query And Index Tuning
56 Query Optimization
Performance Schema for MySQL Troubleshooting
MySQL performance tuning

More from Sveta Smirnova (20)

PDF
War Story: Removing Offensive Language from Percona Toolkit
PDF
MySQL 2024: Зачем переходить на MySQL 8, если в 5.х всё устраивает?
PDF
Database in Kubernetes: Diagnostics and Monitoring
PDF
MySQL Database Monitoring: Must, Good and Nice to Have
PDF
MySQL Cookbook: Recipes for Developers
PDF
MySQL Performance for DevOps
PDF
MySQL Test Framework для поддержки клиентов и верификации багов
PDF
MySQL Cookbook: Recipes for Your Business
PDF
Introduction into MySQL Query Tuning for Dev[Op]s
PDF
Производительность MySQL для DevOps
PDF
MySQL Performance for DevOps
PDF
How to Avoid Pitfalls in Schema Upgrade with Percona XtraDB Cluster
PDF
How to migrate from MySQL to MariaDB without tears
PDF
Modern solutions for modern database load: improvements in the latest MariaDB...
PDF
How Safe is Asynchronous Master-Master Setup?
PDF
Современному хайлоду - современные решения: MySQL 8.0 и улучшения Percona
PDF
How to Avoid Pitfalls in Schema Upgrade with Galera
PDF
How Safe is Asynchronous Master-Master Setup?
PDF
Billion Goods in Few Categories: How Histograms Save a Life?
PDF
A Billion Goods in a Few Categories: When Optimizer Histograms Help and When ...
War Story: Removing Offensive Language from Percona Toolkit
MySQL 2024: Зачем переходить на MySQL 8, если в 5.х всё устраивает?
Database in Kubernetes: Diagnostics and Monitoring
MySQL Database Monitoring: Must, Good and Nice to Have
MySQL Cookbook: Recipes for Developers
MySQL Performance for DevOps
MySQL Test Framework для поддержки клиентов и верификации багов
MySQL Cookbook: Recipes for Your Business
Introduction into MySQL Query Tuning for Dev[Op]s
Производительность MySQL для DevOps
MySQL Performance for DevOps
How to Avoid Pitfalls in Schema Upgrade with Percona XtraDB Cluster
How to migrate from MySQL to MariaDB without tears
Modern solutions for modern database load: improvements in the latest MariaDB...
How Safe is Asynchronous Master-Master Setup?
Современному хайлоду - современные решения: MySQL 8.0 и улучшения Percona
How to Avoid Pitfalls in Schema Upgrade with Galera
How Safe is Asynchronous Master-Master Setup?
Billion Goods in Few Categories: How Histograms Save a Life?
A Billion Goods in a Few Categories: When Optimizer Histograms Help and When ...

Recently uploaded (20)

PPTX
CHAPTER 2 - PM Management and IT Context
PDF
Adobe Illustrator 28.6 Crack My Vision of Vector Design
PDF
How to Choose the Right IT Partner for Your Business in Malaysia
PPTX
Transform Your Business with a Software ERP System
PPTX
Reimagine Home Health with the Power of Agentic AI​
PPTX
Odoo POS Development Services by CandidRoot Solutions
PDF
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
PDF
Which alternative to Crystal Reports is best for small or large businesses.pdf
PDF
Nekopoi APK 2025 free lastest update
PDF
Design an Analysis of Algorithms II-SECS-1021-03
PDF
Odoo Companies in India – Driving Business Transformation.pdf
PDF
System and Network Administration Chapter 2
PPTX
Lecture 3: Operating Systems Introduction to Computer Hardware Systems
PDF
Flood Susceptibility Mapping Using Image-Based 2D-CNN Deep Learnin. Overview ...
PDF
PTS Company Brochure 2025 (1).pdf.......
PDF
How Creative Agencies Leverage Project Management Software.pdf
PDF
System and Network Administraation Chapter 3
PDF
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
PDF
Navsoft: AI-Powered Business Solutions & Custom Software Development
PPTX
Operating system designcfffgfgggggggvggggggggg
CHAPTER 2 - PM Management and IT Context
Adobe Illustrator 28.6 Crack My Vision of Vector Design
How to Choose the Right IT Partner for Your Business in Malaysia
Transform Your Business with a Software ERP System
Reimagine Home Health with the Power of Agentic AI​
Odoo POS Development Services by CandidRoot Solutions
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
Which alternative to Crystal Reports is best for small or large businesses.pdf
Nekopoi APK 2025 free lastest update
Design an Analysis of Algorithms II-SECS-1021-03
Odoo Companies in India – Driving Business Transformation.pdf
System and Network Administration Chapter 2
Lecture 3: Operating Systems Introduction to Computer Hardware Systems
Flood Susceptibility Mapping Using Image-Based 2D-CNN Deep Learnin. Overview ...
PTS Company Brochure 2025 (1).pdf.......
How Creative Agencies Leverage Project Management Software.pdf
System and Network Administraation Chapter 3
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
Navsoft: AI-Powered Business Solutions & Custom Software Development
Operating system designcfffgfgggggggvggggggggg

Why Use EXPLAIN FORMAT=JSON?

  • 1. EXPLAIN FORMAT=JSON Why to use? April, 19, 2016 Sveta Smirnova
  • 2. •The appearance •Innovations •Grouping and ordering •Subqueries and unions •Troubleshooting sugar Table of Contents 2
  • 3. • Has nice structured view • Easily machine-readable • Allows MySQL Workbench draw nice graphs EXPLAIN FORMAT=JSON was introduced in 5.6 3
  • 4. • It has more information than regular EXPLAIN • Can replace OPTIMIZER TRACE for some cases Trendy? - Not only! 4
  • 6. • According to user manual • The percentage of rows that were actually needed, against the equal or bigger number of resolved rows. • Is this good or bad? What number of ”filtered” rows mean? 6
  • 7. • According to user manual • Example query mysql> select * from Country where Name=’Russian Federation’G *************************** 1. row *************************** Code: RUS Name: Russian Federation Continent: Europe ... HeadOfState: Vladimir Putin Capital: 3580 Code2: RU 1 row in set (0.00 sec) What number of ”filtered” rows mean? 6
  • 8. • According to user manual • Example query • Regular EXPLAIN mysql> explain select * from Country where Name=’Russian Federation’; +-----+------+----------+-------------+ | ... | rows | filtered | Extra | +-----+------+----------+-------------+ | ... | 239 | 10.00 | Using where | +-----+------+----------+-------------+ • What happened with rows? • Why they were filtered? What number of ”filtered” rows mean? 6
  • 9. • According to user manual • Example query • Regular EXPLAIN • EXPLAIN FORMAT=JSON has the answer "table": { "table_name": "Country", "access_type": "ALL", "rows_examined_per_scan": 239, "rows_produced_per_join": 23, "filtered": "10.00", What number of ”filtered” rows mean? 6
  • 10. • Covered indexes • Usually use more than one column • Contain all fields, necessary to resolve the query When to use covered indexes? 7
  • 11. • Covered indexes • Example mysql> select count(*) from Country -> where Continent=’Africa’ and Population > 1000000; +----------+ | count(*) | +----------+ | 47 | +----------+ 1 row in set (0,00 sec) • Will the query use Primary Key? • Or * will look through all rows? When to use covered indexes? 7
  • 12. • Covered indexes • Example • EXPLAIN FORMAT=JSON has the answer mysql> explain format=json select count(*) from Country -> where Continent=’Africa’ and Population > 1000000G *************************** 1. row *************************** ... "used_columns": [ "Continent", "Population" ], ... When to use covered indexes? 7
  • 13. • Covered indexes • Example • EXPLAIN FORMAT=JSON has the answer • We only need Continent and Population columns for the index When to use covered indexes? 7
  • 14. • Example queries SELECT first_name, last_name FROM employees WHERE first_name=’Steve’; ...first_name=’Steve’ and last_name like ’V%’; ...first_name=’Steve’ and last_name like ’V%’ and hire_date>’1990-01-01’; Which part of index used? 8
  • 15. • Example queries • Candidate indexes CREATE INDEX comp1(first_name); CREATE INDEX comp2(first_name, last_name); CREATE INDEX comp3(first_name, last_name, hire_date); • Last one seem to fit all the queries Which part of index used? 8
  • 16. • Example queries • Candidate indexes • Index effectiveness mysql> explain format=json SELECT first_name, last_name FROM employees -> WHERE first_name=’Steve’ and last_name like ’V%’ -> and hire_date > ’1990-01-01’G *************************** 1. row *************************** EXPLAIN: { ... "used_key_parts": [ "first_name", "last_name" ], Which part of index used? 8
  • 17. • Example queries • Candidate indexes • Index effectiveness • Column hire date is not used! • Most effective index would be on (first name, last name) Which part of index used? 8
  • 18. • Use case • Table has two or more indexes • All can be used to resolve the query • But only one is chosen • Why? Why index chosen? 9
  • 19. • Use case • Example • Table ‘titles‘ in ‘employees‘ database • The query: select distinct title from titles where year(from_date) > ’1990’; • Two indexes: PRIMARY KEY (‘emp no‘,‘title‘,‘from date‘) KEY ‘emp no‘ (‘emp no‘) Why index chosen? 9
  • 20. • Use case • Example • Index emp no has been chosen mysql> explain select distinct title from titles -> where year(from_date) > ’1990’G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: titles partitions: NULL type: index possible_keys: PRIMARY,emp_no key: emp_no Why index chosen? 9
  • 21. • Use case • Example • Index emp no has been chosen • The reason • Cost statistics for emp no mysql> explain format=json select distinct title -> from titles where year(from_date) > ’1990’G ... "cost_info": { "query_cost": "89796.80" }, ... Why index chosen? 9
  • 22. • Use case • Example • Index emp no has been chosen • The reason "duplicates_removal": { ... "cost_info": { "read_cost": "1252.00", "eval_cost": "88544.80", "prefix_cost": "89796.80", "data_read_per_join": "27M" }, Why index chosen? 9
  • 23. • Use case • Example • Index emp no has been chosen • The reason • Cost statistics for PRIMARY KEY mysql> explain format=json select distinct title from titles -> force index(primary) where year(from_date) > ’1990’G ... "cost_info": { "query_cost": "531269.80" }, ... Why index chosen? 9
  • 24. • Use case • Example • Index emp no has been chosen • The reason • Access by PRIMARY KEY is 531269.80 / 89796.80 = 6 times more expensive! Why index chosen? 9
  • 26. • Hierarchical structure "grouping_operation": { "using_filesort": false, "table": { ... How GROUP BY proceed 11
  • 27. • Hierarchical structure • Allows to distinguish operations "grouping_operation": { "using_temporary_table": true, "using_filesort": true, "cost_info": { "sort_cost": "26.41" }, "nested_loop": [ { ... How GROUP BY proceed 11
  • 28. • Hierarchical structure • Allows to distinguish operations • Separate member for DISTINCT "duplicates_removal": { "using_temporary_table": true, "using_filesort": false, "grouping_operation": { "using_temporary_table": true, "using_filesort": true, ... How GROUP BY proceed 11
  • 29. • Clearly shows which job required • Is temporary table for ORDER BY? mysql> explain select distinct last_name -> from employees order by last_name ascG *************************** 1. row *************************** ... type: ALL ... rows: 299379 filtered: 100.00 Extra: Using temporary; Using filesort 1 row in set, 1 warning (0.00 sec) Ordering operations 12
  • 30. • Clearly shows which job required • Is temporary table for ORDER BY? • Lets check what really happened: mysql> explain format=json select distinct last_name -> from employees order by last_name ascG ... "ordering_operation": { "using_filesort": false, - No temporary table here! "duplicates_removal": { "using_temporary_table": true, "using_filesort": true, ... Ordering operations 12
  • 31. • Clearly shows which job required • Is temporary table for ORDER BY? • Lets check what really happened: • Confirmation mysql> explain format=json select last_name -> from employees order by last_name ascG ... "ordering_operation": { "using_filesort": true, "cost_info": { "sort_cost": "299379.00" ... Ordering operations 12
  • 33. • attached subqueries • Subqueries which are not converted to JOIN mysql> explain format=json select emp_no from salaries -> where salary > (select avg(salary) from salaries)G *************************** 1. row *************************** ... "attached_subqueries": [ { "dependent": false, "cacheable": true, "query_block": { "select_id": 2, ... Everything about subqueries 14
  • 34. • attached subqueries • optimized away subqueries • Subqueries that were executed only once and were replaced by their result. mysql> explain format=json select emp_no, salary from salaries -> order by (select max(salary) from salaries)G ... "optimized_away_subqueries": [ { "dependent": false, "cacheable": true, ... Everything about subqueries 14
  • 35. • attached subqueries • optimized away subqueries • Compare with regular EXPLAIN mysql> explain select emp_no, salary from salaries -> order by (select max(salary) from salaries)G ... *************************** 2. row *************************** id: 2 | key: NULL select_type: SUBQUERY | key_len: NULL table: salaries | ref: NULL partitions: NULL | rows: 2838525 type: ALL | filtered: 100.00 possible_keys: NULL | Extra: NULL Everything about subqueries 14
  • 36. • attached subqueries • optimized away subqueries • materialized from subquery • Materialized subquery mysql> explain format=json select dept_name from departments where -> dept_no in (select dept_no from dept_manager -> where to_date is not null)G ... "table": { | "materialized_from_subquery": { "table_name": "<subquery2>",| "using_temporary_table": true, "access_type": "eq_ref", | "query_block": { ... Everything about subqueries 14
  • 37. • order by subqueries • group by subqueries • having subqueries • Dependent or not • Cacheable or not • If was optimized away • Information about nested subqueries Subqueries and GROUP/ORDER BY 15
  • 38. • All members in parent object union result • Each query exists in query specifications array mysql> explain format=json select Name from City -> union select Capital from CountryG *************************** 1. row *************************** EXPLAIN: { | "table": { "query_block": { | "table_name": "City", "union_result": { | ... ... | "table": { "query_specifications": [ | "table_name": "Country", { ... UNION details 16
  • 40. • The issue: temporary table • SQL BUFFER RESULT always uses it • But how to ensure if original query does not? mysql> explain select sql_buffer_result emp_no, salary/avg(salary) -> from salaries group by emp_no, salaryG *************************** 1. row *************************** id: 1 | key_len: NULL select_type: SIMPLE | ref: NULL table: salaries | rows: 2557022 partitions: NULL | filtered: 100.00 type: ALL | Extra: Using temporary; Using filesort possible_keys: NULL key: NULL SQL BUFFER RESULT is not hidden 18
  • 41. • The issue: temporary table • EXPLAIN FORMAT=JSON distinguish buffer and original query mysql> explain format=json select sql_buffer_result emp_no, -> salary/avg(salary) from salaries group by emp_no, salaryG ... "grouping_operation": { "using_temporary_table": true, "using_filesort": true, ... "buffer_result": { "using_temporary_table": true, ... SQL BUFFER RESULT is not hidden 18
  • 42. • Issue: complicated queries • Regular EXPLAIN lists tables in rows mysql> explain select * from employees join dept_manager using (emp_no) where emp_no in (select emp_no from (select ... *************************** 1. row *************************** table: <subquery2> *************************** 2. row *************************** table: dept_manager *************************** 3. row *************************** table: employees *************************** 4. row *************************** table: <derived3> ... nested loop and JOIN hierarchy 19
  • 43. • Issue: complicated queries • Solution: hierarchical structure mysql> explain format=json select * from employees join dept_manager -> using (emp_no) where emp_no in (select emp_no... ... "nested_loop": [ { "table": { "table_name": "<subquery2>", ... "nested_loop": [ { "table": { "table_name": "titles", ... { "table": { "table_name": "dept_manager", ... nested loop and JOIN hierarchy 19
  • 44. • Provides more details than regular EXPLAIN • However only necessary information for DBA • Elegant way to show it • Machine-readable • Trace details in easy-to-view format EXPLAIN FORMAT=JSON is Cool! 20
  • 45. • EXPLAIN in the official user manual • EXPLAIN FORMAT=JSON is Cool! series More information 21
  • 46. ??? Place for your questions 22