1 准备数据

1.1 建表

  1. DROP TABLE IF EXISTS staff;
  2. CREATE TABLE IF NOT EXISTS staff (
  3. id INT PRIMARY KEY auto_increment,
  4. name ),
  5. age INT,
  6. pos ) COMMENT '职位',
  7. salary ,)
  8. );

1.2 插入数据

  1. , );

2 测试&Explain分析

2.1 有索引的情况下%的影响(提出问题)

2.1.1 建立索引

  1. CREATE INDEX idx_nameAgePos ON staff(name, age, pos);

2.1.2 测试&Explain分析

Case#1:两边都是%

  1. EXPLAIN SELECT * FROM staff WHERE name LIKE '%Alice%';

结果:type=all,全表扫描

Case#2:左边是%

  1. EXPLAIN SELECT * FROM staff WHERE name LIKE '%Alice';

结果:type=all,全表扫描

Case#3:右边是%

  1. EXPLAIN SELECT * FROM staff WHERE name LIKE 'Alice%';

结果:type=range,效果还可以。

对上面三个例子的总结:

  • 都是 SELECT *
  • %在左边,即使有索引,也会失效
  • 只有当%在右边时,才会生效

但问题是,生产环境中,就是要支持模糊查询(%在右边是不够的),一定要两边都是%来查询,这可咋办?

2.2 无索引情况下的查询汇总

2.2.1 删除索引

  1. DROP INDEX idx_nameAgePos ON staff;

2.2.2 测试&Explain分析(主要为了和 2.3.2 节做对比测试)

Case#4:查询Id

  1. EXPLAIN SELECT id FROM staff WHERE name LIKE '%Alice%';

Case#5:查询name

  1. EXPLAIN SELECT name FROM staff WHERE name LIKE '%Alice%';

Case#6:查询age

  1. EXPLAIN SELECT age FROM staff WHERE name LIKE '%Alice%';

Case#7:查询 id & name

  1. EXPLAIN SELECT id, name FROM staff WHERE name LIKE '%Alice%';

Case#8:查询 name & age

  1. EXPLAIN SELECT name, age FROM staff WHERE name LIKE '%Alice%';

Case#9:查询 id & name & age

  1. EXPLAIN SELECT id, name, age FROM staff WHERE name LIKE '%Alice%';

Case#10:查询 id & name & age & salary (提示:salary 不在索引列中,后面会用上)

  1. EXPLAIN SELECT id, name, age, salary FROM staff WHERE name LIKE '%Alice%';

Case#11:查询 *

  1. EXPLAIN SELECT * FROM staff WHERE name LIKE '%Alice%';

从 Case#4 到 Case#11 可以看出,在没有索引的情况下,两边都使用 % 来查询,不管想查询哪个字段(包括查询Id),全部都是全表扫描。

2.3 有索引情况下的查询汇总

2.3.1 建立索引

  1. CREATE INDEX idx_nameAgePos ON staff(name, age, pos);

2.3.2 测试&Explain分析

IndexCase#4:查询Id

  1. EXPLAIN SELECT id FROM staff WHERE name LIKE '%Alice%';

结果:使用上了索引(因为 name 有索引,同时查询的 Id 是主键肯定也有索引)

IndexCase#5:查询name

  1. EXPLAIN SELECT name FROM staff WHERE name LIKE '%Alice%';

结果:使用上了索引(因为查询条件和查询字段都是有索引的 name)

IndexCase#6:查询age

  1. EXPLAIN SELECT age FROM staff WHERE name LIKE '%Alice%';

结果:使用上了索引(因为查询条件的 name 以及查询字段的 age 都有索引)

IndexCase#7:查询 id & name

  1. EXPLAIN SELECT id, name FROM staff WHERE name LIKE '%Alice%';

结果:使用上了索引(因为查询条件的 name 以及查询字段的 id & name 都有索引)

IndexCase#8:查询 name & age

  1. EXPLAIN SELECT name, age FROM staff WHERE name LIKE '%Alice%';

结果:使用上了索引(因为查询条件的 name 以及查询字段的 name & age 都有索引)

IndexCase#9:查询 id & name & age

  1. EXPLAIN SELECT id, name, age FROM staff WHERE name LIKE '%Alice%';

结果:使用上了索引(因为查询条件的 name 以及查询字段的 id & name & age 都有索引)

IndexCase#10:查询 id & name & age & salary (提示:salary 不在索引列中)

  1. EXPLAIN SELECT id, name, age, salary FROM staff WHERE name LIKE '%Alice%';

结果:没有索引,type=all,全表扫描!(因为查询字段中多了个 salary 而 salary 不在索引列中)

IndexCase#11:查询 *

  1. 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使用索引如何避免失效的更多相关文章

  1. 【Java面试】这道互联网高频面试题难住了80%的程序员?索引什么时候失效?

    "索引什么时候失效?" 面试过程中,突如其来的一个问题,是不是有点懵? 没关系,关注我,面试不迷路. 我是Mic,一个工作了14年的Java程序员. 索引失效涉及到的知识点非常多, ...

  2. SQL优化 MySQL版 - 避免索引失效原则(二)

    避免索引失效原则(二) 注:继上一篇文章继续讲解: 避免索引失效原则(一)https://www.cnblogs.com/StanleyBlogs/p/10482048.html#4195062 作者 ...

  3. SQL优化 MySQL版 - 避免索引失效原则(一)

    避免索引失效原则(一) 精力有限,剩余的失效原则将会在 <避免索引失效原则(二)>中连载出来,请谅解 作者 : Stanley 罗昊 [转载请注明出处和署名,谢谢!] 避免索引失效的一些原 ...

  4. Mysql 索引失效场景

    例如:一张USER表   有字段属性 name,age   其中name为索引 下面列举几个索引失效的情况 1. select * from USER where name=‘xzz’ or age= ...

  5. 3、MySQL 索引失效的场景

    索引失效的场景: 1.没有 where 条件 直接看 SQL 语句   2.where 条件中所在的列没有建立索引 show index from t;   3.从表中取得数据超过某个阈值.通常认为是 ...

  6. MySQL优化之避免索引失效的方法

    在上一篇文章中,通过分析执行计划的字段说明,大体说了一下索引优化过程中的一些注意点,那么如何才能避免索引失效呢?本篇文章将来讨论这个问题. 避免索引失效的常见方法 1.对于复合索引的使用,应按照索引建 ...

  7. 1.mysql表优化和避免索引失效原则

    表优化 1.单表优化 建立索引 根据sql的实际解析顺序建立复合索引 最佳左前缀,保持索引的定义和使用顺序一致 2.多表优化 连接查询 小表驱动大表:对于双层循环来说,外层循环(数据量)越小,内层循环 ...

  8. MySQL中为避免索引失效所需注意的问题

    一.索引介绍 二.索引的优势与劣势 1.优势 类似于书籍的目录索引,提高数据检索的效率,降低数据库的IO成本. 通过索引列对数据进行排序,降低数据排序的成本,降低CPU的消耗. 2.劣势 实际上索引也 ...

  9. 面试突击60:什么情况会导致 MySQL 索引失效?

    为了验证 MySQL 中哪些情况下会导致索引失效,我们可以借助 explain 执行计划来分析索引失效的具体场景. explain 使用如下,只需要在查询的 SQL 前面添加上 explain 关键字 ...

随机推荐

  1. jsp文件中文乱码解决

    文件顶加上 <%@ page contentType="text/html;charset=UTF-8" language="java" %>即可

  2. java 使用 ArrayList 排序【包括数字和字符串】

    1.数字排序 /** * 数字排序 */ @Test public void t2() { List<Integer> list = new ArrayList<>(); li ...

  3. PPT制作手机滑动粗糙效果

    原文链接:https://www.toutiao.com/i6495291974680052238/ 选择"插入"选项卡,"插图"功能组."形状&qu ...

  4. HTML5基本结构和语法

    1.1HTML5文档基本结构 HTML5文档省略了<html>,<head>,<body>等元素,使用HTML5的DOCTYRE声明文档类型,简化<meta& ...

  5. 论文翻译:2021_AEC IN A NETSHELL: ON TARGET AND TOPOLOGY CHOICES FOR FCRN ACOUSTIC ECHO CANCELLATION

    论文地址:https://ieeexploreieee.53yu.com/abstract/document/9414715 Netshell 中的 AEC:关于 FCRN 声学回声消除的目标和拓扑选 ...

  6. HDOJ3579Hello Kiki

    https://acm.hdu.edu.cn/showproblem.php?pid=3579 一些坑点.首先是如果说最后求得到的结果为0,那么在数学意义上这是正确的,0对于任何的确是最小的整数解,但 ...

  7. Centos上通过yum命令删除有关MySQL

    1.停止mysql 服务service mysql stop 2.刚开始使用的yum安装的,使用以下语句进行卸载 yum remove mysql* 3.然后删除mysql旧版本已经存在的文件或者数据 ...

  8. 【记录一个问题】linux下使用opencv中的UMat,性能并未提升,反而略有下降

    使用后性能略微下降,一开始怀疑是UMat拷贝的问题.运行 nvidia-smi -l 1, 发现GPU占用始终为0.说明opencl使用的是CPU版本,而不是GPU版本.明天试验opencl的GPU版 ...

  9. dp问题解题思路

    [基本问题单元的定义]这取决于你所查看问题的角度,找到一个划分,推进问题的角度十分重要.作者找到的方式是dp[ i ][ j ],用来表示 substring( i , j),然后站在这个角度,假设s ...

  10. gin中使用路由组

    package main import ( "github.com/gin-gonic/gin" ) func main() { router := gin.Default() / ...