A lot has happened in MySQL 5.6 for queries joining many tables.
For the most common use cases we have drastically reduced the
cost of finding the execution plan. We have also improved the
heuristics and removed bugs so that the final plan is often
better than it used to be. Read on if you are one of those people
who do 15 way joins!
Finding a query execution plan
First some background. You can skip this part if you know how
MySQL picks the table join order in 5.5.
When presented with a query, MySQL will try to find the best
order to join tables by employing a greedy search algorithm. The
outcome is what we call a query execution plan, QEP. When you
join just a few tables, there's no problem calculating the cost
of all join order combinations and then pick the best plan.
However, since there are (#tables)! possible combinations, the
cost of calculating them all soon becomes too high: for five
tables, e.g., …
The latest from the MySQL community
Ideas, releases, practical guides, and perspectives from the people building with MySQL.
Many people consider this information in the MySQL Query Execution Plan (QEP) to indicate that the referenced table is using an index. It actually means that ONLY the index is used. This can for larger and more frequent queries provide a significant boost.
In a recent example, adding an index dropped a query from 190ms to 6ms. However adding a better index dropped that 6ms query to 1.2ms. When executed 100s/1000s of times per second these millisecond improvements can have a huge benefit in greater scalability. While people often tune slow running queries, in a well tuned system shaving milliseconds of queries, in this example making 6ms query 80% better is a far greater improvement.
You can get a detailed explanation of how to identify, create and verify covering indexes from my Percona Live presentation Improving performance …
[Read more]While most people look at performance optimizations for SELECT statements, UPDATE and DELETE statements are often overlooked. These can benefit from the principles of analyzing the Query Execution Plan (QEP). You can only run an EXPLAIN on a SELECT statement, however it’s possible to rewrite an UPDATE or DELETE statement to perform like a SELECT statement.
To optimize an UPDATE, look at the WHERE clause. If you are using the PRIMARY KEY, no further analysis is necessary. If you are not, it is of benefit to rewrite your UPDATE statement as a SELECT statement and obtain a QEP as previously detailed to ensure optimal indexes are used. For example:
UPDATE t SET c1 = ‘x’, c2 = ‘y’, c3 = 100 WHERE c1 = ‘x’ AND d = CURDATE()
You can rewrite this UPDATE statement as a SELECT statement for using EXPLAIN:
EXPLAIN SELECT c1, c2, c3 FROM t WHERE c1 = ‘x’ AND d = CURDATE()
You should …
[Read more]Before you think I’ve posted an animal story in my MySQL category please read on. For reference, The RAT and the CAT is something I wrote back in 2006, that explains the CAT part.
I was reviewing the website performance tonight of a client. I had access to an idle system so being lazy in collecting SQL after my initial audit of the system and MySQL, I turned on the General Query log and hit the home page. NOTE: Do not do this on a running production system, especially with any volume.
What I got was 77 lines of output (after I removed newlines in the queries). 74 were queries, and 72 were from the same table, via some unnecessarily complex sub-joins. I wish I could have laughed but it wasn’t really funny.
My Friday wisdom for writing SQL is this:
- Don’t write duplicate SQL statements
- Look the entire …
I was surprised to find yesterday when using MySQL 5.1.26-rc with a client I’m recommending 5.1 to, some information not seen in the EXPLAIN plan before while reviewing SQL Statements.
Using join buffer
+----+-------------+-------+--------+---------------+--------------+---------+------------------------+-------+----------------------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+--------+---------------+--------------+---------+------------------------+-------+----------------------------------------------+ | 1 | SIMPLE | lr | ALL | NULL | NULL | NULL | NULL | 1084 | Using where; Using temporary; Using filesort | | 1 | SIMPLE | ca | ref | update_check | update_check | 4 | XXXXXXXXXXXXXXXXX | 4 | Using …[Read more]