我们正在将mysql从5.5升级到5.6,现在一些查询速度非常慢。
之前需要0.005秒的查询现在需要49秒。
5.6上的查询正在跳过索引,似乎是:
+----+-------------+-------+-------+----------------------------------------------------+---------+---------+------+--------+-------------+
| 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)
但是不要在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)
这两个DB都是从同一个mysql转储创建的。
当我在5.6上导入时,是否没有构建这些索引?如何强制创建索引?
查询:
SELECT `pens`.* FROM `pens` WHERE (slug_hash = 'style' OR slug = 'style') ORDER BY `pens`.`id` DESC LIMIT 1
编辑:删除架构
答案 0 :(得分:3)
最终上面接受的答案是正确的。
来自@RandomSeed的帮助让我思考正确的方向。基本上5.6中创建的优化计划与5.5中的优化计划有很大不同,因此您可能需要重新编写查询,就像我一样。
我最终没有使用FORCE INDEX
,而是删除了部分查询,直到我确定导致5.6错过索引的原因。然后我重新设计了应用程序逻辑来处理它。
答案 1 :(得分:1)
v5.6中的慢查询是由引擎无法或决定不合并两个相关索引(index_contents_on_slug_hash,index_contents_on_slug)以处理您的查询引起的。请记住,查询每个表只能使用一个索引。为了能够利用同一个表上的多个索引,它需要将这些索引预先合并为一个(在内存中)。这是执行计划中index_merge
和Using 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)的值可能比旧版安装中的值小得多。