like使用索引如何避免失效
1 准备数据
1.1 建表
- DROP TABLE IF EXISTS staff;
- CREATE TABLE IF NOT EXISTS staff (
- id INT PRIMARY KEY auto_increment,
- name ),
- age INT,
- pos ) COMMENT '职位',
- salary ,)
- );
1.2 插入数据
- , );
2 测试&Explain分析
2.1 有索引的情况下%的影响(提出问题)
2.1.1 建立索引
- CREATE INDEX idx_nameAgePos ON staff(name, age, pos);
2.1.2 测试&Explain分析
Case#1:两边都是%
- EXPLAIN SELECT * FROM staff WHERE name LIKE '%Alice%';
结果:type=all,全表扫描
Case#2:左边是%
- EXPLAIN SELECT * FROM staff WHERE name LIKE '%Alice';
结果:type=all,全表扫描
Case#3:右边是%
- EXPLAIN SELECT * FROM staff WHERE name LIKE 'Alice%';
结果:type=range,效果还可以。
对上面三个例子的总结:
- 都是 SELECT *
- %在左边,即使有索引,也会失效
- 只有当%在右边时,才会生效
但问题是,生产环境中,就是要支持模糊查询(%在右边是不够的),一定要两边都是%来查询,这可咋办?
2.2 无索引情况下的查询汇总
2.2.1 删除索引
- DROP INDEX idx_nameAgePos ON staff;
2.2.2 测试&Explain分析(主要为了和 2.3.2 节做对比测试)
Case#4:查询Id
- EXPLAIN SELECT id FROM staff WHERE name LIKE '%Alice%';
Case#5:查询name
- EXPLAIN SELECT name FROM staff WHERE name LIKE '%Alice%';
Case#6:查询age
- EXPLAIN SELECT age FROM staff WHERE name LIKE '%Alice%';
Case#7:查询 id & name
- EXPLAIN SELECT id, name FROM staff WHERE name LIKE '%Alice%';
Case#8:查询 name & age
- EXPLAIN SELECT name, age FROM staff WHERE name LIKE '%Alice%';
Case#9:查询 id & name & age
- EXPLAIN SELECT id, name, age FROM staff WHERE name LIKE '%Alice%';
Case#10:查询 id & name & age & salary (提示:salary 不在索引列中,后面会用上)
- EXPLAIN SELECT id, name, age, salary FROM staff WHERE name LIKE '%Alice%';
Case#11:查询 *
- EXPLAIN SELECT * FROM staff WHERE name LIKE '%Alice%';
从 Case#4 到 Case#11 可以看出,在没有索引的情况下,两边都使用 % 来查询,不管想查询哪个字段(包括查询Id),全部都是全表扫描。
2.3 有索引情况下的查询汇总
2.3.1 建立索引
- CREATE INDEX idx_nameAgePos ON staff(name, age, pos);
2.3.2 测试&Explain分析
IndexCase#4:查询Id
- EXPLAIN SELECT id FROM staff WHERE name LIKE '%Alice%';
结果:使用上了索引(因为 name 有索引,同时查询的 Id 是主键肯定也有索引)
IndexCase#5:查询name
- EXPLAIN SELECT name FROM staff WHERE name LIKE '%Alice%';
结果:使用上了索引(因为查询条件和查询字段都是有索引的 name)
IndexCase#6:查询age
- EXPLAIN SELECT age FROM staff WHERE name LIKE '%Alice%';
结果:使用上了索引(因为查询条件的 name 以及查询字段的 age 都有索引)
IndexCase#7:查询 id & name
- EXPLAIN SELECT id, name FROM staff WHERE name LIKE '%Alice%';
结果:使用上了索引(因为查询条件的 name 以及查询字段的 id & name 都有索引)
IndexCase#8:查询 name & age
- EXPLAIN SELECT name, age FROM staff WHERE name LIKE '%Alice%';
结果:使用上了索引(因为查询条件的 name 以及查询字段的 name & age 都有索引)
IndexCase#9:查询 id & name & age
- EXPLAIN SELECT id, name, age FROM staff WHERE name LIKE '%Alice%';
结果:使用上了索引(因为查询条件的 name 以及查询字段的 id & name & age 都有索引)
IndexCase#10:查询 id & name & age & salary (提示:salary 不在索引列中)
- EXPLAIN SELECT id, name, age, salary FROM staff WHERE name LIKE '%Alice%';
结果:没有索引,type=all,全表扫描!(因为查询字段中多了个 salary 而 salary 不在索引列中)
IndexCase#11:查询 *
- EXPLAIN SELECT * FROM staff WHERE name LIKE '%Alice%';
结果:没有索引,type=all,全表扫描!(因为 * 包含 salary 而 salary 不在索引列中)
通过 IndexCase#4 到 IndexCase#11 可以看出,当真的需要两边都使用%来模糊查询时,只有当这个作为模糊查询的条件字段(例子中的name)以及所想要查询出来的数据字段(例子中的 id & name & age)都在索引列上时,才能真正使用索引,否则,索引失效全表扫描(比如多了一个 salary 字段)。我想,这应该就是 ‘覆盖索引(索引覆盖)’ 的本质吧。同时,这也能很好的证实 “尽量避免SELECT * 而是一一罗列出所需要查询的字段” 的道理吧,因为,搞不好 SELECT * 就多了一个字段,就导致了全表扫描。
3 结论
LIKE以%开头会导致索引失效;使用覆盖索引解决之
like使用索引如何避免失效的更多相关文章
- 【Java面试】这道互联网高频面试题难住了80%的程序员?索引什么时候失效?
"索引什么时候失效?" 面试过程中,突如其来的一个问题,是不是有点懵? 没关系,关注我,面试不迷路. 我是Mic,一个工作了14年的Java程序员. 索引失效涉及到的知识点非常多, ...
- SQL优化 MySQL版 - 避免索引失效原则(二)
避免索引失效原则(二) 注:继上一篇文章继续讲解: 避免索引失效原则(一)https://www.cnblogs.com/StanleyBlogs/p/10482048.html#4195062 作者 ...
- SQL优化 MySQL版 - 避免索引失效原则(一)
避免索引失效原则(一) 精力有限,剩余的失效原则将会在 <避免索引失效原则(二)>中连载出来,请谅解 作者 : Stanley 罗昊 [转载请注明出处和署名,谢谢!] 避免索引失效的一些原 ...
- Mysql 索引失效场景
例如:一张USER表 有字段属性 name,age 其中name为索引 下面列举几个索引失效的情况 1. select * from USER where name=‘xzz’ or age= ...
- 3、MySQL 索引失效的场景
索引失效的场景: 1.没有 where 条件 直接看 SQL 语句 2.where 条件中所在的列没有建立索引 show index from t; 3.从表中取得数据超过某个阈值.通常认为是 ...
- MySQL优化之避免索引失效的方法
在上一篇文章中,通过分析执行计划的字段说明,大体说了一下索引优化过程中的一些注意点,那么如何才能避免索引失效呢?本篇文章将来讨论这个问题. 避免索引失效的常见方法 1.对于复合索引的使用,应按照索引建 ...
- 1.mysql表优化和避免索引失效原则
表优化 1.单表优化 建立索引 根据sql的实际解析顺序建立复合索引 最佳左前缀,保持索引的定义和使用顺序一致 2.多表优化 连接查询 小表驱动大表:对于双层循环来说,外层循环(数据量)越小,内层循环 ...
- MySQL中为避免索引失效所需注意的问题
一.索引介绍 二.索引的优势与劣势 1.优势 类似于书籍的目录索引,提高数据检索的效率,降低数据库的IO成本. 通过索引列对数据进行排序,降低数据排序的成本,降低CPU的消耗. 2.劣势 实际上索引也 ...
- 面试突击60:什么情况会导致 MySQL 索引失效?
为了验证 MySQL 中哪些情况下会导致索引失效,我们可以借助 explain 执行计划来分析索引失效的具体场景. explain 使用如下,只需要在查询的 SQL 前面添加上 explain 关键字 ...
随机推荐
- concat模糊查询
<if test="name!=null"> name like concat('%',concat(#{name},'%')) </if> choose ...
- [ vue ] 监听v-model数据的变化,只要有变化就改变vuex的state值
场景描述: 1. 注册弹出框是用 v-model 绑定数据 showRegisterModal 实现的,点击遮罩层框架会把 showRegisterModal=false 2.REGISTER按 ...
- ANT之macrodef
macrodef 的意思是宏定义, 可以理解为自定义函数. 对于大型部署,可以提高代码利用率. 为了方便理解,请看代码示例: <macrodef name="macro-send-fi ...
- SQL高级优化系列
目录 SQL高级优化系列(一)之MySQL优化 SQL高级优化系列(二)之MySQL架构 SQL高级优化系列(三)之存储引擎 SQL高级优化系列(四)之SQL优化 SQL高级优化系列(五)之执行计划 ...
- unittest测试框架
unittest单元测试框架不仅可以适用于单元测试,还可以适用WEB自动化测试用例的开发与执行,该测试框架可组织执行测试用例,并且提供了丰富的断言方法,判断测试用例是否通过,最终生成测试结果. 一.u ...
- 【linux】Ubuntu20.04使用apt下载和卸载openJDK
Ubuntu20.04使用apt下载和卸载openJDK 前言 由于最近电脑装了ubuntu和win双系统,想再ubuntu上学习.在成功配置完系统之后,开始了配学习环境的旅程.... 这次的是使用u ...
- golang gin框架中实现大文件的流式上传
一般来说,通过c.Request.FormFile()获取文件的时候,所有内容都全部读到了内存.如果是个巨大的文件,则可能内存会爆掉:且,有的时候我们需要一边上传一边处理. 以下的代码实现了大文件流式 ...
- 实习之bii--关于虚拟机桥接无线网卡
安装完VMware workstation之后,网络连接里会多出两个虚拟网卡: VMware Network Adapter VMnet1和VMware Network Adapter VMnet8. ...
- SaltStack 的基本概念与工作原理 架构设计
随着云计算技术的快速普及与发展,越来越多的企业开始学习和搭建自己的云平台代替传统的 IT 交付模式,企业的 IT 环境也随之越来越复杂,常规的运维方法与技术已经无法满足现在云环境中系统的配置与变更.基 ...
- elasticsearch 申请basic证书
如果elasticsearch使用低于6.3版本的,basic证书默认1个月,需要申请,可使用时间为1年. 申请地址为: https://license.elastic.co/registration ...