当前位置:网站首页>【MySQL系列】- LIKE查询 以%开头一定会让索引失效吗
【MySQL系列】- LIKE查询 以%开头一定会让索引失效吗
2022-08-02 11:31:00 【索码理】
MySQL查询导致索引失效的情况有很多,通过搜索引擎搜索MySQL索引失效 几乎都会提到一个情况,那就是like查询以“%”开头。但是 LIKE查询 以%开头一定会让索引失效吗?

验证准备
创建一张users表,表结构如下,表中有999999条数据:

在name字段上创建索引

验证阶段
要验证一段SQL语句有没有使用到索引,最好的方法莫过于使用SQL执行计划EXPLAIN了。
首先先看一下LIKE查询不以%开头的情况:
EXPLAIN SELECT * FROM users WHERE `name` LIKE '001%';

type=range,key=idx_name,说明这段是使用了索引的。
接着再看一下LIKE查询不以%开头的情况 先看第一段SQL语句:
EXPLAIN SELECT * FROM users WHERE `name` LIKE '%001%'

type=ALL,所以这段SQL是没有使用索引的。
再来看第二段SQL语句:
EXPLAIN SELECT `name` FROM users WHERE `name` LIKE '%001%';

type=index,key=idx_name,这个结果说明这段SQL是使用了索引的。
接着看第三段SQL语句:
EXPLAIN SELECT id , `name` FROM users WHERE `name` LIKE '%001%';

第三段SQL语句是在第二段SQL语句的基础上多查询一列id。这个执行结果和第二段是一样的,说明这段也是使用了索引的。
最后看一下第四段SQL语句:
EXPLAIN SELECT id , `name` , gender FROM users WHERE `name` LIKE '%001%';

第四段SQL语句是在第三段SQL语句的基础上多查询两列id和gender。执行结果和第一段一样,是没有使用索引的。
验证结果
通过以上验证可以发现,LIKE查询 以%开头不一定会让索引失效。
为什么会走索引呢?
首先解释一下,执行计划中type=ALL和index。还有key的含义。
type=ALL:全表扫描,遍历整张表去查询匹配的结果,不走索引。 type=index:使用索引覆盖,仅仅扫描索引树,比ALL要快。 type=range:使用索引进行范围查询时就会用到range访问方法。 key:实际使用到的索引,如果为NULL就是没使用索引。
LIKE查询以%开头使用了索引的原因就是使用了索引覆盖。
针对二级索引MySQL提供了一个优化技术。即从辅助索引中就可以得到查询的记录,就不需要回表再根据聚集索引查询一次完整记录。使用索引覆盖的一个好处是辅助索引不包含整行记录的所有信息,故其大小要远小于聚集索引,因此可以减少大量的IO操作,但是前提是要查询的所有列必须都加了索引。
LIKE查询以%开头会导致全索引扫描或者全表扫描,如果没有索引覆盖的话,查询到的数据会回表,多了一次IO操作,当MySQL预估全表扫描或全索引扫描的时间比走索引花费的时间更少时,就不会走索引。有了索引覆盖就不需要回表了,减少了IO操作,花费的时间更少,所以就使用了索引。
总结
LIKE查询 以%开头不一定会让索引失效。如果查询的结果中只包含主键和索引字段则会使用索引,反之则不会。
能力一般,水平有限,如有错误,请多指出。
如果文章对你有用就点个关注给个赞呗
边栏推荐
- 【2022 小目标检测综述】Towards Large-Scale Small Object Detection: Survey and Benchmarks
- Several reasons why applet plugins benefit developers
- 博云入选Gartner中国DevOps代表厂商
- C#/VB.NET to add more lines more columns image watermark into the Word document
- sva 断言资料
- 8大软件供应链攻击事件概述
- Running yum reports Error: Cannot retrieve metalink for reposit
- Oracle 19c配置ob server
- npm WARN config global `--global`, `--local` are deprecated. Use `--location解决方案
- QT笔记——Q_PROPERTY了解
猜你喜欢
yolo格式(txt)数据集转VOC(xml)
Outsourced Student Management System Architecture Documentation
基于深度学习的裂缝检测技术
基于深度学习的裂缝检测技术
使用kubesphere图形界面创建一个devops的CI/CD流程
深度学习100例 —— 卷积神经网络(CNN)实现mnist手写数字识别
华为eNSP(基础实验通信)
LeetCode每日一练 —— 20. 有效的括号
STM32+MPU6050 Design Portable Mini Desktop Clock (Automatically Adjust Time Display Direction)
如何通过DBeaver 连接 TDengine?
随机推荐
When not to use () instead of Void in Swift
doc2vec和word2vec(zigbee简介及应用)
划分训练集,验证集,测试集
LeetCode第三题(Longest Substring Without Repeating Characters)三部曲之一
bgp与mpls综合实验
C#/VB.NET to add more lines more columns image watermark into the Word document
go语言的接口
大疆P4M云遮挡矫正
JSP中include指令的功能简介说明
智能手表前景如何?
Camera Hal OEM模块 ---- cmr_snapshot.c
深度学习100例 —— 卷积神经网络(CNN)实现mnist手写数字识别
SQL函数 $TRANSLATE
List排序 ,取最大值最小值
流动性质押挖矿系统开发如何制作?单双币系统开发成熟技术
leetcode: 200. 岛屿数量
基于深度学习的裂缝检测技术
情景剧《重走长征路》上演
ES2020-23简单易懂又实用的精选特性讲解 日常开发必备干货!
leetcode: 200. Number of islands