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

4

2 回答 2

3

最终,上面接受的答案是正确的。

@RandomSeed 的帮助让我朝着正确的方向思考。基本上,在 5.6 中创建的优化计划与在 5.5 中创建的优化计划有很大不同,因此您可能必须像我一样重新编写查询。

我最终没有使用FORCE INDEX,而是删除了部分查询,直到我确定是什么导致 5.6 丢失索引。然后我重新设计了应用程序逻辑来处理这个问题。

于 2013-07-30T15:34:49.120 回答
1

v5.6 中的慢查询是由于引擎无法或决定不合并两个相关索引(index_contents_on_slug_hash、index_contents_on_slug)以处理您的查询。请记住,查询可能只使用每个表的一个索引。为了能够利用同一张表上的多个索引,它需要动态地将这些索引预先合并为一个(在内存中)。这就是执行计划中的index_mergeUsing union(...)通知的含义。显然,这会消耗时间和内存。

slug快速修复(无论如何可能是首选解决方案):在和上添加一个两列索引slug_hash

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

现在您的新服务器可能无法合并这些索引,因为它会导致索引太大而无法放入缓冲区。您的新服务器key_buffer_size(如果表是 MyISAM)或innodb_buffer_pool_size(如果 InnoDB)的值可能比旧安装中的值小得多。

于 2013-07-29T20:50:49.203 回答