1

We're upgrading mysql from 5.5 to 5.6 and some queries are deadly slow now.

Queries that took 0.005 seconds before are now taking 49 seconds.

Queries on 5.6 are skipping the indexes, it seems:

+----+-------------+-------+-------+----------------------------------------------------+---------+---------+------+--------+-------------+
| id | select_type | table | type  | possible_keys                                      | key     | key_len | ref  | rows   | Extra       |
+----+-------------+-------+-------+----------------------------------------------------+---------+---------+------+--------+-------------+
|  1 | SIMPLE      | pens  | index | index_contents_on_slug,index_contents_on_slug_hash | PRIMARY | 4       | NULL | 471440 | Using where |
+----+-------------+-------+-------+----------------------------------------------------+---------+---------+------+--------+-------------+
1 row in set (0.00 sec)

But are not being skipped on 5.5:

+----+-------------+-------+-------------+----------------------------------------------------+----------------------------------------------------+---------+------+------+----------------------------------------------------------------------------------------------+
| id | select_type | table | type        | possible_keys                                      | key                                                | key_len | ref  | rows | Extra                                                                                        |
+----+-------------+-------+-------------+----------------------------------------------------+----------------------------------------------------+---------+------+------+----------------------------------------------------------------------------------------------+
|  1 | SIMPLE      | pens  | index_merge | index_contents_on_slug,index_contents_on_slug_hash | index_contents_on_slug_hash,index_contents_on_slug | 768,768 | NULL |    2 | Using union(index_contents_on_slug_hash,index_contents_on_slug); Using where; Using filesort |
+----+-------------+-------+-------------+----------------------------------------------------+----------------------------------------------------+---------+------+------+----------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

Both DBs were created from the same mysql dump.

Are these indexes not being constructed when I do the import on 5.6? How do I force the index creation?

The query:

SELECT  `pens`.* FROM `pens`  WHERE (slug_hash = 'style' OR slug = 'style') ORDER BY `pens`.`id` DESC LIMIT 1

Edit: Removed the schema

timsabat
  • 2,208
  • 3
  • 25
  • 34
  • Can you please show the table schema and the query? – Flo Doe Jul 29 '13 at 18:39
  • You can rewrite the query as a UNION or try `IGNORE INDEX (PRIMARY)`. I'm not sure ignore will work in this case but its worth a try. – Vatev Jul 29 '13 at 19:15
  • Added more schema info. As you can see, this is a single table, not a union. The query seems to be missing the index on the slug and slug_hash – timsabat Jul 29 '13 at 19:40

2 Answers2

3

Ultimately the accepted answer above is correct.

The help from @RandomSeed got me thinking in the right direction. Basically the optimization plans created in 5.6 are significantly different from those in 5.5, so you'll probably have to rework your query, much like I did.

I did not end up using the FORCE INDEX, but instead removed portions of the query until I determined what was causing 5.6 to miss the index. Then I reworked the application logic to deal with that.

timsabat
  • 2,208
  • 3
  • 25
  • 34
1

The slow query in v5.6 is caused by the engine being unable to, or deciding not to, merge the two relevant indexes (index_contents_on_slug_hash, index_contents_on_slug) in order to process your query. Remember that a query may only use one index per table. In order to be able to take advantage of several indexes on the same table, it needs to pre-merge on-the-fly these indexes into one (in memory). This is the meaning of the index_merge and Using union(...) notices in your execution plan. This consumes time and memory, obviously.

Quick fix (and probably preferred solution anyways): add a two-colums index on slug and slug_hash.

ALTER TABLE pens ADD INDEX index_contents_on_slug_and_slug_hash (
    slug, slug_hash
);

Now your new server is probably unable to merge these indexes because it results in an index too large to fit in the buffer. Your new server probably has a much smaller value for key_buffer_size (if the table is MyISAM) or for innodb_buffer_pool_size (if InnoDB) than there used to be in your older installation.

RandomSeed
  • 29,301
  • 6
  • 52
  • 87
  • I'm still coming up short. I've upped the innodb_buffer_pool_size like so: `| innodb_buffer_pool_size | 1572864000 |` and restarted. I also added the index you proposed above and I still get a 45 second query not using the indexes. Any other suggestions? – timsabat Jul 29 '13 at 21:16
  • Try adding a `FORCE INDEX (index_contents_on_slug_hash, index_contents_on_slug)` clause (just before the `WHERE` clause). Also try removing the `ORDER BY` clause. Is the execution plan any different? – RandomSeed Jul 29 '13 at 21:21
  • Hm, so the `FORCE INDEX` helped, but did not bring us to an acceptable place. 10s on the first query, and 9s on each subsequent. Does it matter that I've switched from Mac OSx and 5.5 installed by HomeBrew and 5.6 installed from the ubuntu .deb provided by mysql? Also, the 5.6 install is running on a Vagrant VM. I thought I'd see a minor performance hit, but nothing like orders of magnitude like I've got here. – timsabat Jul 29 '13 at 21:30
  • I can't answer for sure, but it shouldn't. However I would always be wary to run a MySQL in a VM. But please, let's compare what is comparable. What does the new execution plan(s) look like? – RandomSeed Jul 29 '13 at 21:40
  • Totally, let's leave the VM out of this, esp. since we're still not hitting the index: https://gist.github.com/tsabat/6108206 – timsabat Jul 29 '13 at 21:53
  • And without the `ORDER BY` clause? – RandomSeed Jul 29 '13 at 21:55
  • Last suggestion: try recomputing the table statistics with an `ANALYZE TABLE pens`. I'm afraid I am running out of ideas. – RandomSeed Jul 29 '13 at 22:00
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/34402/discussion-between-timsabat-and-randomseed) – timsabat Jul 29 '13 at 22:02