当 name 字段添加了索引后,in 查询耗时 0.02 毫秒左右。
EXPLAIN 分析发现它们的 type 都是 range,表示使用索引范围查询, 通过索引字段范围获取表中部分数据记录. 这个类型通常出现在 =,<>,>,>=,,BETWEEN,IN() 操作中。而且 possible_keys 的值也表明了分别使用主键索引和 index_xttblog_name 索引。并且在 in 索引的情况下,rows 的值,大家都可以看到是 4。以上就可以证明了,在 MySQL 5.6 版本中,in 在有索引的情况下,会走索引进行查询。
虽然 Extra 的值是 Using where,它表示优化器需要通过索引回表查询数据。使用了 WHERE 从句来限制哪些行将与下一张表匹配或者是返回给用户。Extra 列出现 Using where 表示 MySQL 服务器将存储引擎返回服务层以后再应用 WHERE 条件过滤。
现在来看,在回答题目中的问题。MySQL 的 in 查询在 5.5 以上的版本中存储引擎都是 innodb 的,正常情况下会走索引的!至于 MyISAM 的情况大家自己去研究,或者我以后抽时间了来写!
如果是 5.5 之前的版本确实不会走索引的,在 5.5 之后的版本,MySQL 做了优化。MySQL 在 2010 年发布 5.5 版本中,优化器对 in 操作符可以自动完成优化,针对建立了索引的列可以使用索引,没有索引的列还是会走全表扫描。
比如,5.5 之前的版本(以下都是 5.5 以前的版本)。select * from a where id in (select id from b); 这条 sql 语句它的执行计划其实并不是先查询出 b 表的所有 id,然后再与 a 表的 id 进行比较。mysql 会把 in 子查询转换成 exists 相关子查询,所以它实际等同于这条 sql 语句:select * from a where exists(select * from b where b.id=a.id);
而 exists 相关子查询的执行原理是:循环取出 a 表的每一条记录与 b 表进行比较,比较的条件是 a.id=b.id。看 a 表的每条记录的 id 是否在 b 表存在,如果存在就行返回 a 表的这条记录。
关于 exists 的问题,我们以后抽时间再说。
互联网上的信息太过广泛,但这不应该成为我们掉以轻心的借口,抱着存疑求是的精神进行甄别,任何信息只有在我们实践验证后方可全信,用在生产开发上的知识,不容有失!
尽信书,不如无书!