SlideShare a Scribd company logo
MySQL EXPLAIN Explained
   Quick and Easy Query Optimisation




   Adrian Hardy <talks@fuzzee.co.uk>
Before we begin...
What you need to know
    How and why we add indexes to tables
●


    The benefits of correct field typing
●


    Understanding of the ideals of 3NF
●


    Basic understanding of SQL JOINs
●




This presentation
    Very quick introduction to EXPLAIN
●



    Improve understanding of MySQL and indexing
●


    Simplified examples / results
●
Introduction - Using MySQL EXPLAIN
  Prefix a SELECT query with EXPLAIN
      MySQL won't actually execute the query, just analyse it
  ●


      EXPLAIN helps us understand how and when MySQL
  ●


      will use indexes
      EXPLAIN returns a table of data from which you identify
  ●


      potential improvements
      Optimise queries in three ways
  ●


           Modify or create indexes
       ●


           Modify query structure
       ●


           Modify data structure
       ●


      Optimised queries = faster results, lower server load...
  ●
Introduction - Review of Indexing
    Fast, compact structure for identifying row locations
●


    Keep indexes in memory by trimming the fat:
●


        Can I reduce the characters in that VARCHAR index?
    ●



        Can I use a TINYINT instead of a BIGINT?
    ●



        Can I use an INTEGER to describe a status or flag (rather
    ●


        than a textual description)?
    Chop down your result set as quickly as possible
●


    MySQL will only use one index per query/table – it cannot
●

    combine two separate indexes to make a useful one *


Understanding and preparation brings about Indexing Strategy



                                  * Not strictly true - look up “Index Merge” operations
Booking application schema

attendees
  attendee_id      surname      conference_id   registration_status
 INTEGER (PK)     VARCHAR       INTEGER (FK)         TINYINT




conferences
 conference_id    location_id     topic_id             date
 INTEGER (PK)    INTEGER (FK)   INTEGER (FK)          DATE
EXPLAIN – Worked Example
     EXPLAIN SELECT * FROM attendees WHERE
conference_id = 123 AND registration_status > 0

           table       possible_keys          key              rows
         attendees         NULL              NULL              14052


   The three most important columns returned by EXPLAIN
    1)Possible keys
         All the possible indexes which MySQL could have used
     ●



         Based on a series of very quick lookups and
     ●

         calculations
    2)Chosen key
    3)Rows scanned
         Indication of effort required to identify your result set
     ●
EXPLAIN – Worked Example
     EXPLAIN SELECT * FROM attendees WHERE
conference_id = 123 AND registration_status > 0

             table      possible_keys          key            rows
           attendees        NULL               NULL       14052


   Interpreting the results
       No suitable indexes for this query
   ●



           MySQL had to do a full table scan
       ●



       Full table scans are almost always the slowest query
   ●



       Full table scans, while not always bad, are usually an
   ●

       indication that an index is required
EXPLAIN – Worked Example
   ALTER TABLE ADD INDEX conf (conference_id);
 ALTER TABLE ADD INDEX reg (registration_status);

EXPLAIN SELECT * FROM attendees WHERE conference_id
         = 123 AND registration_status > 1;

            table       possible_keys           key      rows
          attendees        conf, reg            conf      331


      MySQL had two indexes to choose from, but discarded “reg”
  ●



      “reg” isn't sufficiently unique
  ●



          The spread of values can also be a factor (e.g when 99% of
      ●

          rows contain the same value)
      Index “uniqueness” is called cardinality
  ●



      There is scope for some performance increase...
  ●



          Lower server load, quicker response
      ●
EXPLAIN – Worked Example
           ALTER TABLE ADD INDEX reg_conf_index
          (registration_status, conference_id);

EXPLAIN SELECT * FROM attendees WHERE conference_id =
           123 AND registration_status > 1;

          table     possible_keys         key         rows
                       reg, conf,
        attendees                    reg_conf_index   204
                    reg_conf_index

        reg_conf_index is a much better choice
    ●



     Note that the other two keys are still available, just
    ●

    not as effective
        Our query is now served well by the new index
    ●
EXPLAIN – Worked Example
              DELETE INDEX conf; DELETE INDEX reg;
EXPLAIN SELECT * FROM attendees WHERE conference_id = 123

           table     possible_keys        key           rows
         attendees       NULL            NULL           14052

       Without the “conf” index, we're back to square one
   ●


       The order in which fields were defined in a composite index
   ●


       affects whether it is available for use in a query
       ● Remember,     we defined our index : (registration_status,
         conference_id)
   Potential workaround:
EXPLAIN SELECT * FROM attendees WHERE conference_id = 123
                AND registration_status >= -1

           table      possible_keys         key          rows
         attendees    reg_conf_index   reg_conf_index     204
EXPLAIN – Example 2
EXPLAIN SELECT * FROM attendees WHERE surname LIKE 'har%';

         table        possible_keys      key           rows
       attendees        surname        surname             234


         MySQL uses an index on surname – which is good.



EXPLAIN SELECT * FROM attendees WHERE surname LIKE '%har%';

         table        possible_keys      key           rows
       attendees          NULL          NULL           14052


                 MySQL doesn't even try to use an index!
EXPLAIN – Example 3
EXPLAIN SELECT * FROM conferences WHERE location_id = 2 OR
                    topic_id IN (4,6,1)

         table      possible_keys         key         rows
                     location_id,
      conferences                        NULL         5043
                       topic_id

           MySQL doesn't use an index, because of the OR

 ALTER TABLE ADD INDEX location_topic (location_id,
                     topic_id);

 EXPLAIN SELECT * FROM conferences WHERE location_id = 2
                  OR topic_id IN (4,6,1)

         table      possible_keys         key         rows
                     location_id,
      conferences                    location_topic    15
                       topic_id,
                    location_topic

     Full table scan avoided – could also use UNION (ALL) trick
EXPLAIN – Example 4
EXPLAIN SELECT * FROM attendees WHERE MD5(conference_id) =
                         MD5(123)
         table      possible_keys      key           rows
       attendees        NULL          NULL          14052

         Understandably, MySQL has to do a full table scan



                     A more realistic example?
          EXPLAIN SELECT * FROM conferences WHERE
               DATE_FORMAT(date,'%a') = 'Sat'

         table      possible_keys      key           rows
      conferences       NULL          NULL           5043

    A good candidate for Optimisation #3 – Modify Data Structure
JOINs
    JOINing together large data sets (>= 100,000) is really
●


    where EXPLAIN becomes useful
    Each JOIN in a query gets its own row in EXPLAIN
●


        Make sure each JOIN condition is FAST
    ●


    Make sure each joined table is getting to its result set
●

    as quickly as possible
    ● The benefits compound if each join requires less

      effort
JOINs – Simple Example
                  EXPLAIN SELECT * FROM
conferences INNER JOIN attendees USING (conference_id)
         WHERE conferences.location_id = 2 AND
           conferences.topic_id IN (4,6,1) AND
            attendees.registration_status > 1


   table            type       possible_keys         key              rows
conferences          ref      conference_topic conference_topic        15

 attendees          ALL            NULL             NULL              14052


           Looks like I need an index on attendees.conference_id

      There are 13 different values for “type”
        ● Another indication of effort, aside from rows scanned

        ● Here, “ALL” is bad – we should be aiming for “ref”

          ● Common values are “const”, “ref”, and “all”

        ● http://dev.mysql.com/doc/refman/5.0/en/using-explain.html
The “extra” column
  With every EXPLAIN, you get an “extra” column, which
  shows additional operations invoked to get your result set.
  table     possible_keys     key          rows           extra
                                                      Using where
attendees         conf       conf          331
                                                      Using filesort

  Some example “extra” values:

        Using   where
    ●


        Using   temporary table
    ●


        Using   filesort
    ●


        Using   index
    ●




  There are many more “extra” values which are discussed in
  the MySQL manual.
“Using filesort”
Avoid, because:
● Doesn't use an index

  ● Involves a full scan of your result set


  ● Employs a generic (i.e. one size fits all)

    algorithm
● Uses the filesystem (eeek)


● Will get slower with more data



It's not all bad...
    Perfectly acceptable provided you get to your
●

    result set as quickly as possible, and keep it
    predictably small
    Sometimes unavoidable - ORDER BY RAND()
●


    ORDER BY operations can use indexes to do the
●


    sorting!
“Using filesort” – Example
 EXPLAIN SELECT * FROM attendees WHERE conference_id = 123
                     ORDER BY surname
    table     possible_keys         key             rows         Extra
  attendees    conference_id    conference_id       331       Using filesort


       MySQL is using an index, but it's sorting the results slowly

ALTER TABLE attendees ADD INDEX conf_surname (conference_id,
                          surname);
 EXPLAIN SELECT * FROM attendees WHERE conference_id = 123
                      ORDER BY surname
    table     possible_keys         key             rows         Extra
               conference_id,
  attendees                     conf_surname        331
               conf_surname

                         We've avoided a filesort
“Using index”
    Celebrate, because:
 MySQL got your results just by consulting the index,
●


  ● Which could well have been sat in memory


●MySQL didn't need to even look at the table to get you your

results
  ● Opening a table can be an expensive operation.


●MySQL can answer the next query more quickly


●The fastest way for you to get your data?




    Particularly useful...
 When you're just interested in a single date or an id
●


●Or the COUNT(), SUM(), AVG() etc. of a field
“Using index” – Example
EXPLAIN SELECT AVG(age) FROM attendees WHERE conference_id
                           = 123
   table         possible_keys         key           rows             Extra
 attendees        conference_id    conference_id     331


  Nothing is actually wrong with this query – it could just be quicker!

 ALTER TABLE attendees ADD INDEX conf_age (conference_id,
                           age);
EXPLAIN SELECT AVG(age) FROM attendees WHERE conference_id
                          = 123
    table        possible_keys          key          rows             Extra
                  conference_id,
  attendees                        conf_surname       331         Using index
                  conf_surname

             Outside of caching, the fastest way to get your data *
                                                                  *Not a guarantee
Moving forward...

Just because your queries are fast now, doesn't mean that they will stay
that way forever

Enable MySQL's Slow Query Log
 ● --log-slow-queries=/var/lib/mysql/slow-query.log

 ● Defaults to logging queries which take more than 10 seconds

 ● --long_query_time=1

 ● Use Percona's “microslow” patch for values < 1 second

 ● Find the query in the log, EXPLAIN it, improve it, rinse and repeat
Moving forward...
Use the command line to identify more general problems
 ● mysqladmin -u dbuser -p -r -i 10 extended-status

 ● Figures are relative, updated every 10 seconds

      ● Slow_queries = number of slow queries in last period

      ● Select_Scan = full table scans

      ● Select_full_join = full scans to complete join operations

      ● Created_tmp_disk_tables = filesorts

      ● Key_read_requests/Key_write_requests

        ● Determine write/read weighting of our application and alter your

          indexes accordingly
MySQL Resources

    http://dev.mysql.com/doc/refman/5.0/en/using-explain.html
●



    High Performance MySQL - Baron Schwartz
●



          ISBN 0596101716
      –

          £20 (Money well spent)
      –

    http://www.mysqlperformanceblog.com
●



              Regular posts
          –

More Related Content

What's hot

Indexing the MySQL Index: Key to performance tuning
Indexing the MySQL Index: Key to performance tuningIndexing the MySQL Index: Key to performance tuning
Indexing the MySQL Index: Key to performance tuning
OSSCube
 

What's hot (20)

[Pgday.Seoul 2021] 1. 예제로 살펴보는 포스트그레스큐엘의 독특한 SQL
[Pgday.Seoul 2021] 1. 예제로 살펴보는 포스트그레스큐엘의 독특한 SQL[Pgday.Seoul 2021] 1. 예제로 살펴보는 포스트그레스큐엘의 독특한 SQL
[Pgday.Seoul 2021] 1. 예제로 살펴보는 포스트그레스큐엘의 독특한 SQL
 
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
 
Advanced pg_stat_statements: Filtering, Regression Testing & more
Advanced pg_stat_statements: Filtering, Regression Testing & moreAdvanced pg_stat_statements: Filtering, Regression Testing & more
Advanced pg_stat_statements: Filtering, Regression Testing & more
 
SQL Macros - Game Changing Feature for SQL Developers?
SQL Macros - Game Changing Feature for SQL Developers?SQL Macros - Game Changing Feature for SQL Developers?
SQL Macros - Game Changing Feature for SQL Developers?
 
Using Optimizer Hints to Improve MySQL Query Performance
Using Optimizer Hints to Improve MySQL Query PerformanceUsing Optimizer Hints to Improve MySQL Query Performance
Using Optimizer Hints to Improve MySQL Query Performance
 
MySQL Performance Tuning: Top 10 Tips
MySQL Performance Tuning: Top 10 TipsMySQL Performance Tuning: Top 10 Tips
MySQL Performance Tuning: Top 10 Tips
 
Indexing the MySQL Index: Key to performance tuning
Indexing the MySQL Index: Key to performance tuningIndexing the MySQL Index: Key to performance tuning
Indexing the MySQL Index: Key to performance tuning
 
Sql query patterns, optimized
Sql query patterns, optimizedSql query patterns, optimized
Sql query patterns, optimized
 
MySQL: Indexing for Better Performance
MySQL: Indexing for Better PerformanceMySQL: Indexing for Better Performance
MySQL: Indexing for Better Performance
 
MySQL8.0_performance_schema.pptx
MySQL8.0_performance_schema.pptxMySQL8.0_performance_schema.pptx
MySQL8.0_performance_schema.pptx
 
More mastering the art of indexing
More mastering the art of indexingMore mastering the art of indexing
More mastering the art of indexing
 
MySQL Advanced Administrator 2021 - 네오클로바
MySQL Advanced Administrator 2021 - 네오클로바MySQL Advanced Administrator 2021 - 네오클로바
MySQL Advanced Administrator 2021 - 네오클로바
 
Get to know PostgreSQL!
Get to know PostgreSQL!Get to know PostgreSQL!
Get to know PostgreSQL!
 
Mentor Your Indexes
Mentor Your IndexesMentor Your Indexes
Mentor Your Indexes
 
5 Steps to PostgreSQL Performance
5 Steps to PostgreSQL Performance5 Steps to PostgreSQL Performance
5 Steps to PostgreSQL Performance
 
MySQL Performance Schema in Action
MySQL Performance Schema in ActionMySQL Performance Schema in Action
MySQL Performance Schema in Action
 
PostgreSQL Deep Internal
PostgreSQL Deep InternalPostgreSQL Deep Internal
PostgreSQL Deep Internal
 
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
 
Wars of MySQL Cluster ( InnoDB Cluster VS Galera )
Wars of MySQL Cluster ( InnoDB Cluster VS Galera ) Wars of MySQL Cluster ( InnoDB Cluster VS Galera )
Wars of MySQL Cluster ( InnoDB Cluster VS Galera )
 
[pgday.Seoul 2022] PostgreSQL구조 - 윤성재
[pgday.Seoul 2022] PostgreSQL구조 - 윤성재[pgday.Seoul 2022] PostgreSQL구조 - 윤성재
[pgday.Seoul 2022] PostgreSQL구조 - 윤성재
 

Similar to Mysql Explain Explained

Scaling MySQL Strategies for Developers
Scaling MySQL Strategies for DevelopersScaling MySQL Strategies for Developers
Scaling MySQL Strategies for Developers
Jonathan Levin
 
Myth busters - performance tuning 101 2007
Myth busters - performance tuning 101 2007Myth busters - performance tuning 101 2007
Myth busters - performance tuning 101 2007
paulguerin
 
Optimizing Queries with Explain
Optimizing Queries with ExplainOptimizing Queries with Explain
Optimizing Queries with Explain
MYXPLAIN
 
Explaining the Postgres Query Optimizer (Bruce Momjian)
Explaining the Postgres Query Optimizer (Bruce Momjian)Explaining the Postgres Query Optimizer (Bruce Momjian)
Explaining the Postgres Query Optimizer (Bruce Momjian)
Ontico
 
Understanding query-execution806
Understanding query-execution806Understanding query-execution806
Understanding query-execution806
yubao fu
 
Understanding Query Execution
Understanding Query ExecutionUnderstanding Query Execution
Understanding Query Execution
webhostingguy
 
My sql with querys
My sql with querysMy sql with querys
My sql with querys
NIRMAL FELIX
 
Database development coding standards
Database development coding standardsDatabase development coding standards
Database development coding standards
Alessandro Baratella
 

Similar to Mysql Explain Explained (20)

Introduction to Databases - query optimizations for MySQL
Introduction to Databases - query optimizations for MySQLIntroduction to Databases - query optimizations for MySQL
Introduction to Databases - query optimizations for MySQL
 
MySQL Performance Optimization
MySQL Performance OptimizationMySQL Performance Optimization
MySQL Performance Optimization
 
Scaling MySQL Strategies for Developers
Scaling MySQL Strategies for DevelopersScaling MySQL Strategies for Developers
Scaling MySQL Strategies for Developers
 
Goldilocks and the Three MySQL Queries
Goldilocks and the Three MySQL QueriesGoldilocks and the Three MySQL Queries
Goldilocks and the Three MySQL Queries
 
Myth busters - performance tuning 101 2007
Myth busters - performance tuning 101 2007Myth busters - performance tuning 101 2007
Myth busters - performance tuning 101 2007
 
Why Use EXPLAIN FORMAT=JSON?
 Why Use EXPLAIN FORMAT=JSON?  Why Use EXPLAIN FORMAT=JSON?
Why Use EXPLAIN FORMAT=JSON?
 
Advanced MySQL Query Optimizations
Advanced MySQL Query OptimizationsAdvanced MySQL Query Optimizations
Advanced MySQL Query Optimizations
 
Optimizing Queries with Explain
Optimizing Queries with ExplainOptimizing Queries with Explain
Optimizing Queries with Explain
 
Top 10 Oracle SQL tuning tips
Top 10 Oracle SQL tuning tipsTop 10 Oracle SQL tuning tips
Top 10 Oracle SQL tuning tips
 
MySQL Indexes
MySQL IndexesMySQL Indexes
MySQL Indexes
 
Explaining the Postgres Query Optimizer (Bruce Momjian)
Explaining the Postgres Query Optimizer (Bruce Momjian)Explaining the Postgres Query Optimizer (Bruce Momjian)
Explaining the Postgres Query Optimizer (Bruce Momjian)
 
My SQL Skills Killed the Server
My SQL Skills Killed the ServerMy SQL Skills Killed the Server
My SQL Skills Killed the Server
 
Sql killedserver
Sql killedserverSql killedserver
Sql killedserver
 
Understanding query-execution806
Understanding query-execution806Understanding query-execution806
Understanding query-execution806
 
Understanding Query Execution
Understanding Query ExecutionUnderstanding Query Execution
Understanding Query Execution
 
My sql with querys
My sql with querysMy sql with querys
My sql with querys
 
Introduction to MySQL Query Tuning for Dev[Op]s
Introduction to MySQL Query Tuning for Dev[Op]sIntroduction to MySQL Query Tuning for Dev[Op]s
Introduction to MySQL Query Tuning for Dev[Op]s
 
Introduction into MySQL Query Tuning
Introduction into MySQL Query TuningIntroduction into MySQL Query Tuning
Introduction into MySQL Query Tuning
 
MySQL for beginners
MySQL for beginnersMySQL for beginners
MySQL for beginners
 
Database development coding standards
Database development coding standardsDatabase development coding standards
Database development coding standards
 

More from Jeremy Coates

Search Lucene
Search LuceneSearch Lucene
Search Lucene
Jeremy Coates
 

More from Jeremy Coates (17)

Cyber Security and GDPR
Cyber Security and GDPRCyber Security and GDPR
Cyber Security and GDPR
 
Aspect Oriented Programming
Aspect Oriented ProgrammingAspect Oriented Programming
Aspect Oriented Programming
 
Why is PHP Awesome
Why is PHP AwesomeWhy is PHP Awesome
Why is PHP Awesome
 
Testing with Codeception
Testing with CodeceptionTesting with Codeception
Testing with Codeception
 
An introduction to Phing the PHP build system (PHPDay, May 2012)
An introduction to Phing the PHP build system (PHPDay, May 2012)An introduction to Phing the PHP build system (PHPDay, May 2012)
An introduction to Phing the PHP build system (PHPDay, May 2012)
 
An introduction to Phing the PHP build system
An introduction to Phing the PHP build systemAn introduction to Phing the PHP build system
An introduction to Phing the PHP build system
 
Insects in your mind
Insects in your mindInsects in your mind
Insects in your mind
 
Phing
PhingPhing
Phing
 
Hudson Continuous Integration for PHP
Hudson Continuous Integration for PHPHudson Continuous Integration for PHP
Hudson Continuous Integration for PHP
 
The Uncertainty Principle
The Uncertainty PrincipleThe Uncertainty Principle
The Uncertainty Principle
 
Exploiting Php With Php
Exploiting Php With PhpExploiting Php With Php
Exploiting Php With Php
 
What's new, what's hot in PHP 5.3
What's new, what's hot in PHP 5.3What's new, what's hot in PHP 5.3
What's new, what's hot in PHP 5.3
 
Kiss Phpnw08
Kiss Phpnw08Kiss Phpnw08
Kiss Phpnw08
 
Regex Basics
Regex BasicsRegex Basics
Regex Basics
 
Search Lucene
Search LuceneSearch Lucene
Search Lucene
 
Introduction to Version Control
Introduction to Version ControlIntroduction to Version Control
Introduction to Version Control
 
PHPNW Conference Update
PHPNW Conference UpdatePHPNW Conference Update
PHPNW Conference Update
 

Recently uploaded

Recently uploaded (20)

Powerful Start- the Key to Project Success, Barbara Laskowska
Powerful Start- the Key to Project Success, Barbara LaskowskaPowerful Start- the Key to Project Success, Barbara Laskowska
Powerful Start- the Key to Project Success, Barbara Laskowska
 
Speed Wins: From Kafka to APIs in Minutes
Speed Wins: From Kafka to APIs in MinutesSpeed Wins: From Kafka to APIs in Minutes
Speed Wins: From Kafka to APIs in Minutes
 
Simplified FDO Manufacturing Flow with TPMs _ Liam at Infineon.pdf
Simplified FDO Manufacturing Flow with TPMs _ Liam at Infineon.pdfSimplified FDO Manufacturing Flow with TPMs _ Liam at Infineon.pdf
Simplified FDO Manufacturing Flow with TPMs _ Liam at Infineon.pdf
 
Integrating Telephony Systems with Salesforce: Insights and Considerations, B...
Integrating Telephony Systems with Salesforce: Insights and Considerations, B...Integrating Telephony Systems with Salesforce: Insights and Considerations, B...
Integrating Telephony Systems with Salesforce: Insights and Considerations, B...
 
Top 10 Symfony Development Companies 2024
Top 10 Symfony Development Companies 2024Top 10 Symfony Development Companies 2024
Top 10 Symfony Development Companies 2024
 
Optimizing NoSQL Performance Through Observability
Optimizing NoSQL Performance Through ObservabilityOptimizing NoSQL Performance Through Observability
Optimizing NoSQL Performance Through Observability
 
What's New in Teams Calling, Meetings and Devices April 2024
What's New in Teams Calling, Meetings and Devices April 2024What's New in Teams Calling, Meetings and Devices April 2024
What's New in Teams Calling, Meetings and Devices April 2024
 
FDO for Camera, Sensor and Networking Device – Commercial Solutions from VinC...
FDO for Camera, Sensor and Networking Device – Commercial Solutions from VinC...FDO for Camera, Sensor and Networking Device – Commercial Solutions from VinC...
FDO for Camera, Sensor and Networking Device – Commercial Solutions from VinC...
 
The Metaverse: Are We There Yet?
The  Metaverse:    Are   We  There  Yet?The  Metaverse:    Are   We  There  Yet?
The Metaverse: Are We There Yet?
 
Designing for Hardware Accessibility at Comcast
Designing for Hardware Accessibility at ComcastDesigning for Hardware Accessibility at Comcast
Designing for Hardware Accessibility at Comcast
 
Demystifying gRPC in .Net by John Staveley
Demystifying gRPC in .Net by John StaveleyDemystifying gRPC in .Net by John Staveley
Demystifying gRPC in .Net by John Staveley
 
Secure Zero Touch enabled Edge compute with Dell NativeEdge via FDO _ Brad at...
Secure Zero Touch enabled Edge compute with Dell NativeEdge via FDO _ Brad at...Secure Zero Touch enabled Edge compute with Dell NativeEdge via FDO _ Brad at...
Secure Zero Touch enabled Edge compute with Dell NativeEdge via FDO _ Brad at...
 
Buy Epson EcoTank L3210 Colour Printer Online.pdf
Buy Epson EcoTank L3210 Colour Printer Online.pdfBuy Epson EcoTank L3210 Colour Printer Online.pdf
Buy Epson EcoTank L3210 Colour Printer Online.pdf
 
Free and Effective: Making Flows Publicly Accessible, Yumi Ibrahimzade
Free and Effective: Making Flows Publicly Accessible, Yumi IbrahimzadeFree and Effective: Making Flows Publicly Accessible, Yumi Ibrahimzade
Free and Effective: Making Flows Publicly Accessible, Yumi Ibrahimzade
 
Strategic AI Integration in Engineering Teams
Strategic AI Integration in Engineering TeamsStrategic AI Integration in Engineering Teams
Strategic AI Integration in Engineering Teams
 
Behind the Scenes From the Manager's Chair: Decoding the Secrets of Successfu...
Behind the Scenes From the Manager's Chair: Decoding the Secrets of Successfu...Behind the Scenes From the Manager's Chair: Decoding the Secrets of Successfu...
Behind the Scenes From the Manager's Chair: Decoding the Secrets of Successfu...
 
Connecting the Dots in Product Design at KAYAK
Connecting the Dots in Product Design at KAYAKConnecting the Dots in Product Design at KAYAK
Connecting the Dots in Product Design at KAYAK
 
Syngulon - Selection technology May 2024.pdf
Syngulon - Selection technology May 2024.pdfSyngulon - Selection technology May 2024.pdf
Syngulon - Selection technology May 2024.pdf
 
PLAI - Acceleration Program for Generative A.I. Startups
PLAI - Acceleration Program for Generative A.I. StartupsPLAI - Acceleration Program for Generative A.I. Startups
PLAI - Acceleration Program for Generative A.I. Startups
 
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptxIOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
 

Mysql Explain Explained

  • 1. MySQL EXPLAIN Explained Quick and Easy Query Optimisation Adrian Hardy <talks@fuzzee.co.uk>
  • 2. Before we begin... What you need to know How and why we add indexes to tables ● The benefits of correct field typing ● Understanding of the ideals of 3NF ● Basic understanding of SQL JOINs ● This presentation Very quick introduction to EXPLAIN ● Improve understanding of MySQL and indexing ● Simplified examples / results ●
  • 3. Introduction - Using MySQL EXPLAIN Prefix a SELECT query with EXPLAIN MySQL won't actually execute the query, just analyse it ● EXPLAIN helps us understand how and when MySQL ● will use indexes EXPLAIN returns a table of data from which you identify ● potential improvements Optimise queries in three ways ● Modify or create indexes ● Modify query structure ● Modify data structure ● Optimised queries = faster results, lower server load... ●
  • 4. Introduction - Review of Indexing Fast, compact structure for identifying row locations ● Keep indexes in memory by trimming the fat: ● Can I reduce the characters in that VARCHAR index? ● Can I use a TINYINT instead of a BIGINT? ● Can I use an INTEGER to describe a status or flag (rather ● than a textual description)? Chop down your result set as quickly as possible ● MySQL will only use one index per query/table – it cannot ● combine two separate indexes to make a useful one * Understanding and preparation brings about Indexing Strategy * Not strictly true - look up “Index Merge” operations
  • 5. Booking application schema attendees attendee_id surname conference_id registration_status INTEGER (PK) VARCHAR INTEGER (FK) TINYINT conferences conference_id location_id topic_id date INTEGER (PK) INTEGER (FK) INTEGER (FK) DATE
  • 6. EXPLAIN – Worked Example EXPLAIN SELECT * FROM attendees WHERE conference_id = 123 AND registration_status > 0 table possible_keys key rows attendees NULL NULL 14052 The three most important columns returned by EXPLAIN 1)Possible keys All the possible indexes which MySQL could have used ● Based on a series of very quick lookups and ● calculations 2)Chosen key 3)Rows scanned Indication of effort required to identify your result set ●
  • 7. EXPLAIN – Worked Example EXPLAIN SELECT * FROM attendees WHERE conference_id = 123 AND registration_status > 0 table possible_keys key rows attendees NULL NULL 14052 Interpreting the results No suitable indexes for this query ● MySQL had to do a full table scan ● Full table scans are almost always the slowest query ● Full table scans, while not always bad, are usually an ● indication that an index is required
  • 8. EXPLAIN – Worked Example ALTER TABLE ADD INDEX conf (conference_id); ALTER TABLE ADD INDEX reg (registration_status); EXPLAIN SELECT * FROM attendees WHERE conference_id = 123 AND registration_status > 1; table possible_keys key rows attendees conf, reg conf 331 MySQL had two indexes to choose from, but discarded “reg” ● “reg” isn't sufficiently unique ● The spread of values can also be a factor (e.g when 99% of ● rows contain the same value) Index “uniqueness” is called cardinality ● There is scope for some performance increase... ● Lower server load, quicker response ●
  • 9. EXPLAIN – Worked Example ALTER TABLE ADD INDEX reg_conf_index (registration_status, conference_id); EXPLAIN SELECT * FROM attendees WHERE conference_id = 123 AND registration_status > 1; table possible_keys key rows reg, conf, attendees reg_conf_index 204 reg_conf_index reg_conf_index is a much better choice ● Note that the other two keys are still available, just ● not as effective Our query is now served well by the new index ●
  • 10. EXPLAIN – Worked Example DELETE INDEX conf; DELETE INDEX reg; EXPLAIN SELECT * FROM attendees WHERE conference_id = 123 table possible_keys key rows attendees NULL NULL 14052 Without the “conf” index, we're back to square one ● The order in which fields were defined in a composite index ● affects whether it is available for use in a query ● Remember, we defined our index : (registration_status, conference_id) Potential workaround: EXPLAIN SELECT * FROM attendees WHERE conference_id = 123 AND registration_status >= -1 table possible_keys key rows attendees reg_conf_index reg_conf_index 204
  • 11. EXPLAIN – Example 2 EXPLAIN SELECT * FROM attendees WHERE surname LIKE 'har%'; table possible_keys key rows attendees surname surname 234 MySQL uses an index on surname – which is good. EXPLAIN SELECT * FROM attendees WHERE surname LIKE '%har%'; table possible_keys key rows attendees NULL NULL 14052 MySQL doesn't even try to use an index!
  • 12. EXPLAIN – Example 3 EXPLAIN SELECT * FROM conferences WHERE location_id = 2 OR topic_id IN (4,6,1) table possible_keys key rows location_id, conferences NULL 5043 topic_id MySQL doesn't use an index, because of the OR ALTER TABLE ADD INDEX location_topic (location_id, topic_id); EXPLAIN SELECT * FROM conferences WHERE location_id = 2 OR topic_id IN (4,6,1) table possible_keys key rows location_id, conferences location_topic 15 topic_id, location_topic Full table scan avoided – could also use UNION (ALL) trick
  • 13. EXPLAIN – Example 4 EXPLAIN SELECT * FROM attendees WHERE MD5(conference_id) = MD5(123) table possible_keys key rows attendees NULL NULL 14052 Understandably, MySQL has to do a full table scan A more realistic example? EXPLAIN SELECT * FROM conferences WHERE DATE_FORMAT(date,'%a') = 'Sat' table possible_keys key rows conferences NULL NULL 5043 A good candidate for Optimisation #3 – Modify Data Structure
  • 14. JOINs JOINing together large data sets (>= 100,000) is really ● where EXPLAIN becomes useful Each JOIN in a query gets its own row in EXPLAIN ● Make sure each JOIN condition is FAST ● Make sure each joined table is getting to its result set ● as quickly as possible ● The benefits compound if each join requires less effort
  • 15. JOINs – Simple Example EXPLAIN SELECT * FROM conferences INNER JOIN attendees USING (conference_id) WHERE conferences.location_id = 2 AND conferences.topic_id IN (4,6,1) AND attendees.registration_status > 1 table type possible_keys key rows conferences ref conference_topic conference_topic 15 attendees ALL NULL NULL 14052 Looks like I need an index on attendees.conference_id There are 13 different values for “type” ● Another indication of effort, aside from rows scanned ● Here, “ALL” is bad – we should be aiming for “ref” ● Common values are “const”, “ref”, and “all” ● http://dev.mysql.com/doc/refman/5.0/en/using-explain.html
  • 16. The “extra” column With every EXPLAIN, you get an “extra” column, which shows additional operations invoked to get your result set. table possible_keys key rows extra Using where attendees conf conf 331 Using filesort Some example “extra” values: Using where ● Using temporary table ● Using filesort ● Using index ● There are many more “extra” values which are discussed in the MySQL manual.
  • 17. “Using filesort” Avoid, because: ● Doesn't use an index ● Involves a full scan of your result set ● Employs a generic (i.e. one size fits all) algorithm ● Uses the filesystem (eeek) ● Will get slower with more data It's not all bad... Perfectly acceptable provided you get to your ● result set as quickly as possible, and keep it predictably small Sometimes unavoidable - ORDER BY RAND() ● ORDER BY operations can use indexes to do the ● sorting!
  • 18. “Using filesort” – Example EXPLAIN SELECT * FROM attendees WHERE conference_id = 123 ORDER BY surname table possible_keys key rows Extra attendees conference_id conference_id 331 Using filesort MySQL is using an index, but it's sorting the results slowly ALTER TABLE attendees ADD INDEX conf_surname (conference_id, surname); EXPLAIN SELECT * FROM attendees WHERE conference_id = 123 ORDER BY surname table possible_keys key rows Extra conference_id, attendees conf_surname 331 conf_surname We've avoided a filesort
  • 19. “Using index” Celebrate, because: MySQL got your results just by consulting the index, ● ● Which could well have been sat in memory ●MySQL didn't need to even look at the table to get you your results ● Opening a table can be an expensive operation. ●MySQL can answer the next query more quickly ●The fastest way for you to get your data? Particularly useful... When you're just interested in a single date or an id ● ●Or the COUNT(), SUM(), AVG() etc. of a field
  • 20. “Using index” – Example EXPLAIN SELECT AVG(age) FROM attendees WHERE conference_id = 123 table possible_keys key rows Extra attendees conference_id conference_id 331 Nothing is actually wrong with this query – it could just be quicker! ALTER TABLE attendees ADD INDEX conf_age (conference_id, age); EXPLAIN SELECT AVG(age) FROM attendees WHERE conference_id = 123 table possible_keys key rows Extra conference_id, attendees conf_surname 331 Using index conf_surname Outside of caching, the fastest way to get your data * *Not a guarantee
  • 21. Moving forward... Just because your queries are fast now, doesn't mean that they will stay that way forever Enable MySQL's Slow Query Log ● --log-slow-queries=/var/lib/mysql/slow-query.log ● Defaults to logging queries which take more than 10 seconds ● --long_query_time=1 ● Use Percona's “microslow” patch for values < 1 second ● Find the query in the log, EXPLAIN it, improve it, rinse and repeat
  • 22. Moving forward... Use the command line to identify more general problems ● mysqladmin -u dbuser -p -r -i 10 extended-status ● Figures are relative, updated every 10 seconds ● Slow_queries = number of slow queries in last period ● Select_Scan = full table scans ● Select_full_join = full scans to complete join operations ● Created_tmp_disk_tables = filesorts ● Key_read_requests/Key_write_requests ● Determine write/read weighting of our application and alter your indexes accordingly
  • 23. MySQL Resources http://dev.mysql.com/doc/refman/5.0/en/using-explain.html ● High Performance MySQL - Baron Schwartz ● ISBN 0596101716 – £20 (Money well spent) – http://www.mysqlperformanceblog.com ● Regular posts –