索引使用规则

  • 联合索引
  • 索引失效情况

联合索引

1.最左前缀法则
如果索引使用了多列(联合索引),要遵守最左前缀法则。最左前缀法则指的是查询从索引的最左列开始,并且不跳过索引中的列,如果跳跃某一列,索引将会部分失效(后面字段的索引失效)。其中对于最左的列必须存在,否则索引将全部失效。


以tb_user为例,tb_user表所创建的索引如上图所示,在tb_user表中 ,id 为主键索引,phone,name为普通索引,还有一个联合索引,联合索引涉及到3个字段,顺序分别为profession,age,status。
最左原则就是在查询时,最左边的列,也就是profession必须存在,否则索引全部失效。而且中间不能跳过某一列,否则该列后面的字段将失效。用以下几组案例来演示:

EXPLAIN SELECT * FROM tb_user WHERE profession = '软件工程' and age = 31 and status = '0';

EXPLAIN SELECT * FROM tb_user WHERE profession = '软件工程' and age = 31 ;

EXPLAIN SELECT * FROM tb_user WHERE profession = '软件工程' ;


以上3组测试中,只要联合索引最左边的字段 profession存在,索引就会生效,只不过索引的长度不同,通过以上3组测试可以得出,profession字段索引长度36,age长度为2,status长度也为2.

EXPLAIN SELECT * FROM tb_user WHERE age = 31 and status  ='0' ;

EXPLAIN SELECT * FROM tb_user WHERE status  ='0' ;


通过上面2组测试看到索引并未生效,原因就是不满足最左前缀法则,联合索引最左边的列profession不存在。

EXPLAIN SELECT * FROM tb_user WHERE profession ='软件工程' and   status  ='0' ;


通过上面这组测试看到profession存在时索引生效,但是在查询时,跳过了age这个列,索引后面的列索引是不会使用的,也就是索引部分失效,索引索引的字段为36。

2.范围查询
在联合索引中,出现范围查询(>,<),范围右侧索引的列索引就失效。

EXPLAIN SELECT * FROM tb_user WHERE profession ='软件工程' and age >30  and   status  ='0' ;


当联合索引使用了范围查询(<,>),索引会生效,但是索引长度为38,就说明范围查询最右边的status字段是没有左索引的。当范围查询使用<= 或者 >=时,则右侧索引的列索引不会失效。

EXPLAIN SELECT * FROM tb_user WHERE profession ='软件工程' and age >=0  and   status  ='0' ;

索引失效情况

**1.不要在索引列上进行运算操作,索引将失效
在tb_user表中,其中phone字段也是一个索引。

当phone字段进行等值匹配时,索引生效。

EXPLAIN SELECT * FROM tb_user WHERE phone ='17799990017'

当phone字段进行函数运算操作之后,索引失效。

EXPLAIN SELECT * FROM tb_user WHERE SUBSTRING(phone ,10,2) = 15;


2.字符串类型字段使用时,不加引号,索引将失效

EXPLAIN SELECT * FROM tb_user WHERE phone = 17799990017


3.模糊查询
如果只是尾部模糊匹配,索引不会失效。如果是头部使用模糊匹配,索引失效。

尾部模糊匹配,索引不失效

EXPLAIN SELECT * FROM tb_user WHERE phone like '17111%'

头部模糊匹配,索引失效

EXPLAIN SELECT * FROM tb_user WHERE phone like '%17'


4.or连接条件
用or分割开的条件,如果or前的条件的列有索引,而后面的列中没有索引,那么涉及的索引都不会被用到。

EXPLAIN SELECT * FROM tb_user WHERE  id =10 or age = 22;


由于age没有索引,所以即使id有索引,索引也会失效。

CREATE INDEX idx_user_age on tb_user(age);

我们可以对age字段建立索引,建立索引后再次执行以上SQL语句,结果如下:

最终发现,当or连接的条件中,左右两侧都有索引时,索引才会生效。
5.不等于(!= 或者<>)索引失效

EXPLAIN SELECT * FROM tb_user WHERE phone <> '123' ;

EXPLAIN SELECT * FROM tb_user WHERE phone != '123' ;

6.数据分布影响
如果Mysql评估使用索引比全表更慢,则不使用索引。

EXPLAIN SELECT * FROM tb_user WHERE  phone > '17799990015' ;

EXPLAIN SELECT * FROM tb_user WHERE  phone > '17799990020' ;


通过以上2组SQL测试得到只是phone查询的值不同,最终的执行计划也完全不一样。这是为啥?
就是因为Mysql在查询时,会评估使用索引的效率与走全表扫描的效率,如果走全表扫描更快,则会放弃索引,走全表扫描。因为索引是用来索引少量数据的,如果通过索引查询返回大批量的数据则还不如走全表扫描来的快,此时索引就会失效。

我们在看看 is null 与 is not null 操作是否走索引。

EXPLAIN SELECT * FROM tb_user WHERE  profession is null ;

EXPLAIN SELECT * FROM tb_user WHERE  profession is not  null ;


接下来,我们做一个操作profession字段值全部更新为null。

update  tb_user set profession = null ;

然后在执行以上2条sql,查看其执行计划


最终看到一模一样的SQL语句,先后执行了两次,结果查看执行计划是不一样的,为什么会出现这种情况呢?还是因为数据库的数据分布有关系。查询Mysql会评估,走索引快还是全表扫描快,如果全表扫描更快,则会放弃索引走全表扫描。因此,is null 、is not null是否走索引,得具体情况具体分析,并不是固定的。

索引使用规则及索引失效情况相关推荐

  1. mysql 索引命中规则 不命中的情况

    mysql 索引命中规则 不命中的情况 多列索引 遵循:最左匹配原则 不会命中索引的情况 案例分析 当一条sql语句提交给mysql数据库进行查询的时候需要经历以下几步 1.先在where解析这一步把 ...

  2. 盘一盘常见的6种索引失效情况

    摘要:今天就来跟大家盘一盘,常见的 6 种会发生索引失效的场景. 本文分享自华为云社区<面试官:聊聊索引失效?失效的原因是什么?>,作者:小林coding . 在工作中,如果我们想提高一条 ...

  3. mysql查询where后面索引失效_where条件索引失效情况

    虽然说索引在使用上可能有种种限制,但是还是在数据库设计中被充分利用.因为在大部分情况下索引还是被用来提高数据库性能的一个工具.不过有些数据库工程师往往会犯一些低级的错误,导致索引失效.如在Where条 ...

  4. 一篇文章了解Like用法及常见索引失效情况

    1.简介 本文主要通过介绍Like索引及常见索引失效情况,以MySQL为例. 2.EXPLAIN关键字 一条查询语句在经过MySQL查询优化器的各种基于成本和规则的优化会后生成一个所谓的执行计划. E ...

  5. is NULL , is NOT NULL 有时索引失效 || in 走索引, not in 索引失效 ||单列索引和复合索引 || 查看索引使用情况

    is NULL , is NOT NULL 有时索引失效 in 走索引, not in 索引失效 单列索引和复合索引 尽量使用复合索引,而少使用单列索引 数据库会选择一个最优的索引(辨识度最高索引)来 ...

  6. MySQL索引原理、失效情况

    声明:本文是小编在学习过程中,东拼西凑整理,如有雷同,纯属借鉴. Mysql5.7的版本, InnoDB引擎 目录 1 mysql索引知识 1.1 B+Tree索引 1.2 主键索引和普通索引的区别 ...

  7. MySQL之索引失效情况

    文章目录 1 MySQL索引 1.1 简介 1.1.1 索引基础 1.2 SQL优化 1.2.1 查看执行计划 1.2.2 show profile分析 1.2.3 trace 2 索引失效 2.1 ...

  8. 十几年老Java咳血推荐:MySQL索引原理、失效情况,两万字肝爆,建议收藏!

    一.前言 MySQL 作为主流的数据库,是各大厂面试官百问不厌的知识点,但是需要了解到什么程度呢?仅仅停留在 建库.创表.增删查改等基本操作的水平可不够.在面试后端开发的时候,一连几个问题,简直会被问 ...

  9. MySQL索引介绍,普通索引,全文索引,空间索引,多列索引使用原则,建立索引常用的规则

    转自:https://blog.csdn.net/tomorrow_fine/article/details/78337735 1.MySQL在创建数据表的时候创建索引 在MySQL中创建表的时候,可 ...

最新文章

  1. 腾讯 Robotics X 实验室首次「开箱」移动机器人,能走梅花桩,还能自平衡
  2. 微信小程序开发之选项卡
  3. PyCharm2017软件安装教程
  4. 介绍一个能避免 CORS 错误的 Chrome 扩展 - Moesif Origin CORS Changer
  5. Winform 的一个多线程绑定DataGrid数据源的例子
  6. Python GUI设计 PythonWx
  7. java 反射和泛型-反射来获取泛型信息
  8. 退出android app时界面残留影响,【Android】App 或 Activity 销毁重建的状态恢复对回调带来的影响...
  9. 网站自动适配技术实现原理
  10. 强悍的电子邮件地址(email address)正则表达式
  11. 最牛通达信短线超强波段主图指标公式 源码
  12. SharePoint CAML Query小结
  13. K3 ERP 系统财务管理 - 账结法、表结法
  14. python selenium Frefox使 用代理访问网页
  15. c语言修改pdf文件内容,PDF怎么编辑修改?如何编辑PDF的内容?
  16. Google点击没有反应怎么办?Google卸载不了怎么办?Google安装不了怎么办?
  17. 只需三步!使用3DCG软件Blender制作时尚图片
  18. fullcalendar的使用教程
  19. 无FTTR不千兆,华为星光F30让家中不再有“隐秘的角落”
  20. InnoDB存储引擎中有页(Page)的概念

热门文章

  1. 研招网:@2021推免生:关于推免,你必须要知道的三件事
  2. 特斯拉(自动驾驶)如何做持续集成和持续交付
  3. Android转接电话到iPhone,如何将iPhone呼叫转接到另一个号码 | MOS86
  4. 990万次骑行: 纽约自行车共享系统分析
  5. 猎户座计划软件测试,麒麟820信心爆棚?评测结果:秒杀骁龙865和猎户座980
  6. 2020/7/27 - [watevrCTF-2019]Cookie Store - 伪造cookie
  7. WUBI 安装常见问题FAQ
  8. 如何规划你的职业生涯
  9. python怎么求圆柱表面积半径和高由键盘输入_从键盘上输入圆的半径,计算圆的周长和面积(使用符号常量)_学小易找答案...
  10. mqtt协议 及emqx,mosquitto的一点看法