Effective MySQL: Optimizing SQL Statements
by Ronald Bradford
No Nonsense, Readable, Practical, and Compact
I like that this book is small; 150 pages means you can carry it easily. It’s also very no nonsense. It does not dig too deeply into theory unless it directly relates to your day-to-day needs. And those needs probably cluster heavily around optimizing SQL queries, as those pesky developers are always breaking things 😉
Jokes aside, this new book out on Oracle Press is a very readable volume. Bradford has drawn directly from real-world experience to give you the right bite size morsels you need in your day-to-day MySQL activities.
Chapter one, The Five Minute DBA gives you the basic methodology if you don’t already know it. Enable the slow query log, analyze it, and use the explain facility. Then index as appropriate, or eliminate queries if you can.
Chapter two digs a little deeper into the basics, introducing explain extended, table statistics and storage engines. You’ll also learn how to use show session & global status, as well as session & global variables. You’ll also have your first look at MySQL’s data dictionary – INFORMATION_SCHEMA.
Chapter three is where it starts to get meaty. You probably know that MySQL has b-tree indexes, but did you know that it has b+tree indexes, or hash indexes?
Chapter four digs into indexes further with single & multi-column indexes using them for sorting and joining. You’ll also find out about covering indexes which are multi-column matching the where clause, but also including columns needed in the SELECT predicate. Do you have duplicate or unused indexes? You’ll learn why they matter to performance and how to eliminate them with tools like mk-duplicate-key-checker.
Chapter five continues along the same lines, with more coverage of indexes. Learn to identify when you are using a covering index, fulfilling the entire query by only accessing the index. You’ll also learn about partial indexes, how they can reduce the size of index storage and retrieval while still getting your data for you.
Chapter six covers configuring the server itself, hitting on the system variables such as the innodb buffer pool (innodb_buffer_pool_size) and key buffer (key_buffer_size) as well as the query cache. You’ll also learn how to set the four main session memory settings – sort buffer (sort_buffer_size) and join buffer ( join_buffer_size) as well as the lesser known read buffers (read_buffer_size and read_rnd_buffer_size).
Chapter seven is all about the process of tuning and optimizing MySQL. Rolling all the previous sections into marching orders, and prescriptive advice, he takes you through step by step how to apply the principles. You’ll get an introduction to mk-query-digest (though strangely without attribution to Baron Schwartz), the great maatkit tool for query analysis and aggregation, as well as the microsecond precision patch, which allows your mysql shell client to display more exact timing data. For the patch he links back to an article on his own site which seems to be not found. The author of the high precision mysql timer patch is Stewart Smith.
I personally got the most out of Chapter eight, full of self-described hidden performance tips. From identifying unused or duplicate indexes, to replacing inefficient data types with better ones, why it’s important to use NOT NULL where possible or how to store IP addresses efficiently, this chapter has a lot of goodies. For those still struggling with SQL statement tuning, there are a few patterns that are described, offering advice on how to rewrite a subquery as an inner join,
What you might not know
- MySQL includes Oracle’s index organized tables by a different name
- Too many indexes can dramatically impact INSERT & UPDATE performance
- Many DDL operations can be done online – see oak-online-alter-table (Shlomi Noach)
- Datatypes matter – use enum, int unsigned, timestamp & not null where possible
- Covering indexes are your friend, duplicate & unused indexes are not!
- A replication slave can have different storage engines or indexes from the master. These can support different uses – such as data warehousing or non-transactional requirements.
- While a_string LIKE ‘%end of my sentence.’ won’t use an index, you can index reverse_string, then use reverse_string LIKE REVERSE ‘%end of my sentence.’ and MySQL will use this index. You’ve simulated an advanced Oracle feature, reverse key indexes!
A few small gripes
If I were to add a few complaints it would be to say that some of the examples were rather simplistic. In many cases tuning SQL is not as simple as just adding the right index. For instance there was no good discussion of the dreaded “using temporary, using filesort” that we see a lot in MySQL explains when sorting has to be done, but will not fit in memory. Or what about tmpdir=/dev/shm, how will that improve things? What about UNION versus UNION ALL where appropriate. Why does DISTINCT do a sort?
The book was also missing a discussion of triggers, stored procedures, when or if the query cache can cause problems and so forth. Also the article link mentioned about chapter seven isn’t the only missing link. I followed links to optimizing sql statements and it seems to go to a generic holding page. Also the main link effectivemysql.com/book leads to an outline of an as yet unreleased title on Backup and Recovery.
All in all, well worth your money
However, other than these few gripes the book overall is a very welcome addition to the small family of MySQL books. Get a copy quick before they’re all gone!