我的代码有趣的MySQL 5.6的行为
SELECT candidate.ID
FROM users u
JOIN users candidate ON candidate.a = u.a AND candidate.b < 1
JOIN user_meta meta ON candidate.id = meta.user_id
WHERE u.id = 1
AND candidate.count > 0
ORDER BY meta.updated_at DESC
LIMIT 100
这短短的片段,并在其周围,我认为是远远慢,所以我开始去查了一下787-8结束英寸我尝试了加入条件的实验
SELECT candidate.ID
FROM users u
JOIN users candidate ON candidate.a = u.a AND candidate.b < 2
JOIN user_meta meta ON candidate.id = meta.user_id
WHERE u.id = 1
AND candidate.count > 0
ORDER BY meta.updated_at DESC
LIMIT 100
并且有趣的是它在80ms内完成。唯一改变的是小于1至小于2
运行EXPLAIN的查询产生以下两个查询
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE u const PRIMARY,index_a PRIMARY 4 const 1 NULL
1 SIMPLE meta index PRIMARY index_meta_on_updated_at 5 NULL 100 Using index
1 SIMPLE candidate eq_ref PRIMARY,index_a PRIMARY 4 db.meta.user_id 1 Using where
也许不是我错过了什么,但可能导致此行为?
对于'candidate.b <1'有多少条记录,以及'candidate.b <2'有多少条记录?做一个单独的查询来找出。您还可以使用'EXPLAIN EXTENDED'和[SHOW _PROFILE](https://dev.mysql.com/doc/refman/5.5/en/show-profile.html)来获取关于MySQL幕后操作的详细信息。 'SHOW PROFILE'会给你详细的信息和时间,每个步骤MySQL执行查询(打开表格,搜索索引或磁盘,通过网络发送等) – Mjh
如果您使用innodb它可能是表( s)在innodb缓冲区(RAM内存)中,因为您执行了第一个查询。可以理解为什么第二个查询执行得更快.. –
关于@RaymondNijland评论,我总是使用'SQL_NO_CACHE'来尝试和帮助比较苹果与苹果,当调查这样的“问题” - 但它不会帮助Innodb缓冲区。 – wally