Xaprb

Stay curious!

Introducing MySQL Visual Explain

with 17 comments

Download MySQL Visual Explain

If you’ve ever wished you could see MySQL’s EXPLAIN output formatted as a tree, now you can. MySQL Visual Explain transforms EXPLAIN output into a hierarchical view of the query plan, which is significantly easier to read and understand.

What it does

MySQL Visual Explain is a command-line tool, not a Graphical User Interface (GUI). You can use it two ways:

  • Give it a query and some connection options, and it will connect and EXPLAIN the query, then show you the result as a tree.
  • Give it the output of EXPLAIN in any of several formats, and it will parse it and turn it into a tree.

Here’s a simple example. Given the following query,

select actor_id,
   (select count(film_id) from sakila.film join sakila.film_actor using(film_id))
from sakila.actor;

You get this EXPLAIN output:

+----+-------------+------------+-------+----------------+--------------------+---------+---------------------+------+-------------+
| id | select_type | table      | type  | possible_keys  | key                | key_len | ref                 | rows | Extra       |
+----+-------------+------------+-------+----------------+--------------------+---------+---------------------+------+-------------+
|  1 | PRIMARY     | actor      | index | NULL           | PRIMARY            | 2       | NULL                |  200 | Using index | 
|  2 | SUBQUERY    | film       | index | PRIMARY        | idx_fk_language_id | 1       | NULL                |  951 | Using index | 
|  2 | SUBQUERY    | film_actor | ref   | idx_fk_film_id | idx_fk_film_id     | 2       | sakila.film.film_id |    2 | Using index | 
+----+-------------+------------+-------+----------------+--------------------+---------+---------------------+------+-------------+

MySQL Visual Explain turns this into the following query execution plan:

SUBQUERY
+- JOIN
|  +- Index lookup
|  |  key            film_actor->idx_fk_film_id
|  |  possible_keys  idx_fk_film_id
|  |  key_len        2
|  |  ref            sakila.film.film_id
|  |  rows           2
|  +- Index scan
|     key            film->idx_fk_language_id
|     possible_keys  PRIMARY
|     key_len        1
|     rows           951
+- Index scan
   key            actor->PRIMARY
   key_len        2
   rows           200

You should read this as a depth-first tree traversal. In other words, the root of the tree is the output node — the last thing that happens in query execution.

As I said, this is a simple example. When your queries have many subqueries and/or UNIONs, you quickly get much more complicated EXPLAIN output, which is very hard to understand. It’s much easier to read the tree representation for complex queries. Here are thumbnails of the query execution plans of some real queries from a project I’ve worked on:

MySQL Visual Explain output on a complex queryMySQL Visual Explain output on a complex query

The corresponding EXPLAIN output is very hard to understand, even though I’ve become an expert on EXPLAIN. I can understand the tree view without trouble. I don’t think it matters how much of an expert I am, a tree view is always going to be easier to understand.

How it works

MySQL Visual Explain tries to reverse-engineer EXPLAIN by re-ordering and dividing the input into parent/child relationships. How exactly it happens is complex, though it can be expressed in code fairly succinctly. I wanted to write this tool nearly a year ago, but after studying EXPLAIN for a while, I found I just didn’t understand it well enough. Then this spring at the MySQL Conference and Expo 2007, I saw a talk on the Query Optimizer by Timour Katchaounov, who works on the optimizer team. Timour helped me grasp how MySQL executes queries. Most importantly, he showed a diagram of the execution plan as a left-deep tree. I always assumed the query execution plan was a bushy tree, but once I saw the left-deep tree I understood more about how MySQL works (for example, I now understand why MySQL doesn’t support FULL OUTER JOIN).

The crucial bridge between that and understanding EXPLAIN was a slide that showed the nodes of the tree mapped to rows in EXPLAIN. This made me see how to approach the problem. After spending hours reading the MySQL manual and source code, and studying many examples, I slowly understood how to go backwards from EXPLAIN to a tree.

It is not as simple as it sounds! There are many details, such as how to decide which nodes should be children of which other nodes (when there are no subqueries or UNIONs, of course it’s trivial). EXPLAIN’s output can be quite complex, and a moderately complicated query takes me a few minutes to reverse-engineer by hand — and most of the time I get it wrong. Maybe I can write the details in another blog post, or contribute them to MySQL’s documentation or the MySQL Forge wiki.

Download it

You can get the goodies from the Sourceforge MySQL Toolkit project page and read the documentation online at the MySQL Toolkit homepage.

If you find bugs

I couldn’t have written this tool without unit tests, especially since I had to start over twice when I found I was misunderstanding something major (that’s a huge plug for test-driven development). If you find a query it transforms wrong, please report it via the project’s Sourceforge bug tracking system. Please give the query and EXPLAIN output, so I can add it to the test suite.

Future plans

MySQL themselves, and many community members, have sometimes discussed the need for a tree view of EXPLAIN. I sincerely hope they implement that feature and make this little tool obsolete in future versions of MySQL. I also understand MySQL is trying to add more information to EXPLAIN. Currently it’s not possible to get a complete query execution plan from EXPLAIN, because it doesn’t show you everything the server does while executing the query. If MySQL adds information, I’ll update this tool. I have a feature request pending to show when a GROUP BY happens, for example.

I also specifically wrote this tool to be useful as a module, not just a command-line utility. This makes it possible for you to use the module in your own programs. I have a few ideas for this myself, though I may not get time to implement them.

Your support appreciated

Though the end result makes it look easy, this was a seriously hard project that took many evenings and weekends of research, testing, and coding, with many false starts. If you feel inclined, there’s a “support” link in the navigation bar at the top of this page! (For those of you who tried to send me something and it got returned, I’ve fixed that issue).

Written by Baron Schwartz

July 29th, 2007 at 1:53 pm

Posted in Uncategorized

Tagged with , , , , ,

17 Responses to 'Introducing MySQL Visual Explain'

Subscribe to comments with RSS

  1. Great work! EXPLAIN can definitely be mysterious.

    evan

    29 Jul 07 at 2:39 pm

  2. Its great to see such a tool come up, For long MySQL lacked something similar to a “Execution Plan” view as in MS-SQL server, I’d like to see a similar tool/could be u’r code into main MySQL client.

  3. [...] mysql visual explain [...]

  4. Great Baron,

    (I know you sent me initial version to review and I did not reply to that email yet, sorry)

    This is a great tool especially for complex queries – EXPLAIN itself works good for Joins but once you get into a lot of subqueries it becomes nasty.

    You may also look at explain options to get more info such as partitions used etc.

    Peter Zaitsev

    30 Jul 07 at 12:43 pm

  5. Thanks Peter.

    Partitions and other options are included, but not output by default if they are NULL. The textual tree-view output actually doesn’t show all the information in the tree built from EXPLAIN; I wanted to keep it as brief as possible. But if your EXPLAIN output includes partitions, you should see the results in the tree.

    This makes me realize, there’s no way with the –connect option to ask MySQL Visual Explain to EXPLAIN the command as EXPLAIN PARTITIONS! I will add an option to do that. This of course only affects what data it gets from the server, not how the tree is built; if you give it text as input instead of a command, it’ll show all the information it’s given.

    [EDIT] I see I’m too smart for myself. It runs EXPLAIN /*!50115 PARTITIONS*/ SELECT so it should work fine. I completely forgot that I did that.

    Xaprb

    30 Jul 07 at 12:51 pm

  6. Baron! This is great, awesome!

    Roland Bouman

    30 Jul 07 at 10:03 pm

  7. [...] Introducing MySQL Visual Explain MySQL Visual Explain transforms EXPLAIN output into a hierarchical view of the query plan, which is significantly easier to read and understand. (tags: MySQL) [...]

  8. [...] Xaprb on Introducing MySQL Visual Explain [...]

  9. Baron,

    This is really cool! FYI, I found a small bug and submitted a bug report per your instructions. The –socket option isn’t working.

    -Dave

    Dave Shrewsbury

    5 Aug 07 at 5:13 pm

  10. Thanks Dave! That probably means it is broken in many other tools too. I’ll take a look.

    Xaprb

    6 Aug 07 at 9:48 am

  11. Great, that’s definately an improvement to the standard EXPLAIN command! Obviously, still some key performance figures are missing from the output from MySQL.

    What do you think about this graphical EXPLAIN view (work in progress):

    http://www.jetprofiler.com/blog/4/best-way-to-visualize-explain/

    Jet Profiler

    6 Nov 08 at 6:20 am

  12. Thanks for all your work on this. I hate to be the only negative comment on this, but your output doesn’t really help explain things much more beyond giving a bit more of a logic flow of things – for the average MySQL programmer who is not an expert, it still doesn’t show why a query might be broken (in terms of performance) or how to speed it up. We still have to go back to all the definitions on the MySQL EXPLAIN syntax to vaguely understand the terminology and derive the hints needed to speed up the query. I am looking for something that my team can use to quickly idenitfy the issues without having to remember the esoteric aspects of explain everytime.

    Thanks again for your efforts.

    Dale

    22 Feb 09 at 9:55 am

  13. For what it’s worth, I created a little web front-end to mk-visual-explain, which is now published at http://explain.plosquare.com

    Jan Ploski

    17 May 10 at 5:07 pm

  14. Jan, that’s awesome! I always sort of intended to do this, if no one else did it first.

    Xaprb

    20 May 10 at 6:24 pm

  15. Crtnly n mprvmnt n MySQL tl st bt nthng cmprd t PstgrSQL tls. Unfrtntly ppl mks bd chcs rgrdng RDBMS nd thn sk s t fx thm whn thy strt t xprnc hvy prfrmnc sss n MySQL. Anywys thnks fr th tl, blv t s hlpng sm, wsh t cld b n pr. Kp th gd jb!

    waldo

    20 Nov 10 at 8:23 pm

  16. I am well aware of PostgreSQL’s merits, but trash-talking any open-source database is harmful and unproductive to all open-source databases. Sniping is not welcome here. The previous comment has been disemvoweled.

    Xaprb

    21 Nov 10 at 9:54 am

Leave a Reply