Like 查询,%百分号在前 ‘%xttblog’ 到底走不走索引?

第一时间获取技术干货和业界资讯!

Like 查询,%百分号在前 ‘%xttblog’ 到底走不走索引?

其实,早期关注我的朋友都知道,我写了一个 MySQL 的 in 查询到底走不走索引。今天我们再来看看 MySQL 的 Like 查询 % 百分号在前的情况是否会走索引。

在面试过程中,我们一般都会说 like 走索引有一个原则,那就是最左匹配原则。那么当 % 号放在最前面的情况,就一定不走索引吗?

Like 查询,%百分号在前 ‘%xttblog’ 到底走不走索引?

我们通过一个例子来看看是否是这样的情况。示例 SQL 我一次性贴出来,如下所示:

Like 查询,%百分号在前 ‘%xttblog’ 到底走不走索引?

注意,我的版本是 MySQL 5.6 。上面 1 到 5 条查询的执行计划基本上如下所示:

Like 查询,%百分号在前 ‘%xttblog’ 到底走不走索引?
根据我前面的这篇文章《拜托别在问我 MySQL 性能优化了!》我们知道,上面的查询都是用到了索引。但是注意第 3 条查询中,possible_keys 为 null。possible_keys 代表的是此次查询中可能选用的索引,那就说明将 % 放在前面的 like 查询虽然 type 和 extra 显示的都好像用了索引,但其实 possible_keys 显示的结果告诉我们并没有使用索引。那实际情况是怎么样的呢?
我们现在就可以下一个结论,在 MySQL 5.6 版本中,Like 查询,会用到索引,但是只要 % 在前就会根据索引进行顺序扫描,不能快速定位,需要顺序遍历。至于没有 %,也会使用索引。 not like 同理。

但是你也别高兴的太早。“用索引” 和 “用索引快速定位记录”是有区别的。“用索引”有一种用法是 “顺序扫描索引”。

Like ‘y’ 或 ‘y%’ 可以使用索引,并且快速定位记录。like ‘%y’ 或 ‘%y%’,只是在二级索引树上遍历查找记录,并不能快速定位(扫描了整棵索引树)。只有 id 和 test_like 字段时,上述 5 种 like 查询,test_like 索引能满足 id 和 test_like 的查询情况,不需要回表,所以选择了使用 test_like 的索引树解决问题。如果新添加了 xtt 字段,但无联合索引 (test_like, xtt) 的情况,如果使用 test_like 索引树,需要回表。在 like ‘%y’ 或 ‘%y%’ 直接扫描主键索引树,现象就是没有使用 test_like 索引。添加了 xtt 字段,也添加了 (test_like, xtt) 索引,使用覆盖索引就能满足 select * 的字段查询,不需要回表,因此使用了 (test_like, xtt) 索引树。但是只有 like ‘y’ 和 ‘y%’ 能快速定位记录,而 like ‘%y’ 和 ‘%y%’ 也能使用该索引树,但是不能快速定位,需要顺序遍历。

其次,index 类型表示”和全表扫描一样。只是扫描表的时候按照索引次序进行而不是行。主要优点就是避免了排序, 但是开销仍然非常大。index 表示性能并不是特别优越,system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL ,一般来说,得保证查询至少达到 range 级别,最好能达到 range 级别。

猜你喜欢

转载自blog.51cto.com/15127565/2666219