Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >京东三面:什么情况会导致 MySQL 索引失效?

京东三面:什么情况会导致 MySQL 索引失效?

原创
作者头像
Java程序猿
发布于 2022-07-29 08:03:28
发布于 2022-07-29 08:03:28
6030
举报
文章被收录于专栏:Java核心技术Java核心技术

前言

为了验证 MySQL 中哪些情况下会导致索引失效,我们可以借助 explain 执行计划来分析索引失效的具体场景。

explain 使用如下,只需要在查询的 SQL 前面添加上 explain 关键字即可,如下图所示:

而以上查询结果的列中,我们最主要观察 key 这一列,key 这一列表示实际使用的索引,如果为 NULL 则表示未使用索引,反之则使用了索引。

以上所有结果列说明如下:

  • id — 选择标识符,id 越大优先级越高,越先被执行;
  • select_type — 表示查询的类型;
  • table — 输出结果集的表;
  • partitions — 匹配的分区;
  • type — 表示表的连接类型;
  • possible_keys — 表示查询时,可能使用的索引;
  • key — 表示实际使用的索引;
  • key_len — 索引字段的长度;
  • ref— 列与索引的比较;
  • rows — 大概估算的行数;
  • filtered — 按表条件过滤的行百分比;
  • Extra — 执行情况的描述和说明。

其中最重要的就是 type 字段,type 值类型如下:

  • all — 扫描全表数据;
  • index — 遍历索引;
  • range — 索引范围查找;
  • index_subquery — 在子查询中使用 ref;
  • unique_subquery — 在子查询中使用 eq_ref;
  • ref_or_null — 对 null 进行索引的优化的 ref;
  • fulltext — 使用全文索引;
  • ref — 使用非唯一索引查找数据;
  • eq_ref — 在 join 查询中使用主键或唯一索引关联;
  • const — 将一个主键放置到 where 后面作为条件查询, MySQL 优化器就能把这次查询优化转化为一个常量,如何转化以及何时转化,这个取决于优化器,这个比 eq_ref 效率高一点。 创建测试表和数据 为了演示和测试那种情况下会导致索引失效,我们先创建一个测试表和相应的数据: -- 创建表 drop table if exists student; create table student( id int primary key auto_increment comment '主键', sn varchar(32) comment '学号', name varchar(250) comment '姓名', age int comment '年龄', sex bit comment '性别', address varchar(250) comment '家庭地址', key idx_address (address), key idx_sn_name_age (sn,name,age) )ENGINE=InnoDB DEFAULT CHARSET=utf8; -- 添加测试数据 insert into student(id,sn,name,age,sex,address) values(1,'cn001','张三',18,1,'高老庄'), (2,'cn002','李四',20,0,'花果山'), (3,'cn003','王五',50,1,'水帘洞'); 复制代码 当前表中总共有 3 个索引,如下图所示:

PS:本文以下内容基于 MySQL 5.7 InnoDB 数据引擎下。

索引失效情况1:非最左匹配

最左匹配原则指的是,以最左边的为起点字段查询可以使用联合索引,否则将不能使用联合索引。 我们本文的联合索引的字段顺序是 sn + name + age,我们假设它们的顺序是 A + B + C,以下联合索引的使用情况如下:

从上述结果可以看出,如果是以最左边开始匹配的字段都可以使用上联合索引,比如:

  • A+B+C
  • A+B
  • A+C 其中:A 等于字段 sn,B 等于字段 name,C 等于字段 age。

而 B+C 却不能使用到联合索引,这就是最左匹配原则。

索引失效情况2:错误模糊查询

模糊查询 like 的常见用法有 3 种:

  1. 模糊匹配后面任意字符:like '张%'
  2. 模糊匹配前面任意字符:like '%张'
  3. 模糊匹配前后任意字符:like '%张%'

而这 3 种模糊查询中只有第 1 种查询方式可以使用到索引,具体执行结果如下:

索引失效情况3:列运算

如果索引列使用了运算,那么索引也会失效,如下图所示:

索引失效情况4:使用函数

查询列如果使用任意 MySQL 提供的函数就会导致索引失效,比如以下列使用了 ifnull 函数之后的执行计划如下:

索引失效情况5:类型转换

如果索引列存在类型转换,那么也不会走索引,比如 address 为字符串类型,而查询的时候设置了 int 类型的值就会导致索引失效,如下图所示:

索引失效情况6:使用 is not null

当在查询中使用了 is not null 也会导致索引失效,而 is null 则会正常触发索引的,如下图所示:

总结

导致 MySQL 索引失效的常见场景有以下 6 种:

  1. 联合索引不满足最左匹配原则。
  2. 模糊查询最前面的为不确定匹配字符。
  3. 索引列参与了运算。
  4. 索引列使用了函数。
  5. 索引列存在类型转换。
  6. 索引列使用 is not null 查询。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
高频js笔试题看这一篇就够了
类的继承在几年前是重点内容,有n种继承方式各有优劣,es6普及后越来越不重要,那么多种写法有点『回字有四样写法』的意思,如果还想深入理解的去看红宝书即可,我们目前只实现一种最理想的继承方式。
helloworld1024
2022/11/04
7640
由浅入深,66条JavaScript面试知识点
来源:https://juejin.im/post/5ef8377f6fb9a07e693a6061
zz_jesse
2020/07/07
1K0
由浅入深,66条JavaScript面试知识点
利用这 66 条 JS 知识抓住年底最后一次跳槽涨薪的机会
作者: Jake Zhang https://juejin.cn/post/6844904200917221389
用户4456933
2021/06/01
7030
利用这 66 条 JS 知识抓住年底最后一次跳槽涨薪的机会
100道+ JavaScript 面试题,助你查漏补缺
详细资料可以参考: 《JavaScript 有几种类型的值?》 《JavaScript 有几种类型的值?能否画一下它们的内存图;》
前端达人
2020/04/08
9000
JavaScript 面试知识点总结
本部分主要是笔者在复习 JavaScript 相关知识和一些相关面试题时所做的笔记,如果出现错误,希望大家指出!
不愿意做鱼的小鲸鱼
2022/09/24
4080
signature=0fdde99449705347b1bc3148e0519684,yarn.lock · mirrors_yeoman/generator-generator – Gitee.co
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
全栈程序员站长
2022/10/02
4540
入坑!通过ajaxreturn jquery json提交form
\Think\Controller类提供了ajaxReturn方法用于AJAX返回数据给客户端(视图、模板、js等)。并且支持JSON、JSONP、XML和EVAL四种方式给客户端接受数据(默认JSON)。
PM吃瓜
2019/08/12
5K0
入坑!通过ajaxreturn jquery json提交form
前端基础进阶(十七):详解 ES6 Modules
历史上,JavaScript 一直没有模块(module)体系,无法将一个大程序拆分成互相依赖的小文件,再用简单的方法拼装起来。其他语言都有这项功能,比如 Ruby 的require、Python 的import,甚至就连 CSS 都有@import,但是 JavaScript 任何这方面的支持都没有,这对开发大型的、复杂的项目形成了巨大障碍。
唐志远
2022/10/27
1.2K0
编写可维护的JavaScript
• 在方法中的局部变量(local variable)和第一条语句之间
硬核项目经理
2019/08/07
8640
JQuery-命令速查-CheatSheet
http://stackoverflow.com/questions/31379409/form-submission-causing-maximum-call-stack-size-exceeded
szhshp
2022/09/21
9.8K0
2021前端面试必备题+答案
如果是 HTTP 1.0 版本协议,一般情况下,不支持长连接,因此在每次请求发送完毕之后,TCP 连接即会断开,因此一个 TCP 发送一个 HTTP 请求,但是有一种情况可以将一条 TCP 连接保持在活跃状态,那就是通过 Connection 和 Keep-Alive 首部,在请求头带上 Connection: Keep-Alive,并且可以通过 Keep-Alive 通用首部中指定的,用逗号分隔的选项调节 keep-alive 的行为,如果客户端和服务端都支持,那么其实也可以发送多条,不过此方式也有限制,可以关注《HTTP 权威指南》4.5.5 节对于 Keep-Alive 连接的限制和规则。
zz1998
2021/07/06
8110
Python全栈之jQuery笔记
jQuery runnoob网址: http://www.runoob.com/jquery/jquery-tutorial.html jQuery API手册: http://www.runoob.com/manual/jquery/ jQuery笔记 笔记来源于: 传智播客的黑马程序员视频笔记. 菜鸟教程:http://www.runoob.com/ 自己的查询与整理. JS的不完美地方: 1. 代码比较麻烦,给多个元素添加事件需要遍历,可能还需要进行嵌套.
py3study
2020/01/19
5.5K0
快速学习-综合案例RESTRUL_CRUD
发起请求,无法执行,因为delete请求必须通过post请求转换为delete请求,借助:HiddenHttpMethodFilter过滤器
cwl_java
2020/02/19
1.8K0
快速学习-综合案例RESTRUL_CRUD
前端MVC Vue2学习总结(七)——ES6与Module模块化、Vue-cli脚手架搭建、开发、发布项目与综合示例
使用vue-cli可以规范项目,提高开发效率,但是使用vue-cli时需要一些ECMAScript6的知识,特别是ES6中的模块管理内容,本章先介绍ES6中的基础与模块化的内容再使用vue-cli开发vue项目。 一、ECMAScript6概要 ECMAScript是一种由Ecma国际(前身为欧洲计算机制造商协会,英文名称是European Computer Manufacturers Association)通过ECMA-262标准化的脚本程序设计语言。这种语言在万维网上应用广泛,它往往被称为JavaSc
张果
2018/03/30
1.8K0
前端MVC Vue2学习总结(七)——ES6与Module模块化、Vue-cli脚手架搭建、开发、发布项目与综合示例
从零实现的浏览器Web脚本
在之前我们介绍了从零实现Chrome扩展,而实际上浏览器级别的扩展整体架构非常复杂,尽管当前有统一规范但不同浏览器的具体实现不尽相同,并且成为开发者并上架Chrome应用商店需要支付5$的注册费,如果我们只是希望在Web页面中进行一些轻量级的脚本编写,使用浏览器扩展级别的能力会显得成本略高,所以在本文我们主要探讨浏览器Web级别的轻量级脚本实现。
WindRunnerMax
2023/11/04
8420
一个Angular 5教程:一步一步指导实现你的第一个Angular 5应用程序
现在我们可以app.component.html用这个替换:Angular是由Google开发的AngularJS框架的新版本。它带有一个完整的重写,以及各种改进,包括优化构建和更快的编译时间。在这个Angular 5教程中,我们将从头开始构建一个笔记应用程序。如果您一直在等待学习Angular 5,本教程适合您。
WindCoder
2018/09/19
42.8K0
一个Angular 5教程:一步一步指导实现你的第一个Angular 5应用程序
Airflow速用
Airflow是Apache用python编写的,用到了 flask框架及相关插件,rabbitmq,celery等(windows不兼容);、
用户1558882
2019/10/31
5.5K0
jquery 实现点击图片居住放大缩小
该功能是基于jquery实现的,所以 第一步则是引入jquery jquery下载地址:https://jquery.com/download/ 或者使用此时调试的版本(3版本) /*! jQuery v3.2.1 | (c) JS Foundation and other contributors | jquery.org/license */ !function(a,b){"use strict";"object"==typeof module&&"object"==typeof module.expo
wfaceboss
2019/04/08
17.3K0
【原创】前端面试知识体系(一)
我的博客来源:https://1024bibi.com/2018/01/01/%E5%89%8D%E7%AB%AF%E9%9D%A2%E8%AF%95%E7%9F%A5%E8%AF%86%E4%BD%93%E7%B3%BB%EF%BC%88%E4%B8%80%EF%BC%89/
达达前端
2023/10/08
2870
2018年最全面的前端面试题都在这里了
意义:根据内容的结构化(内容语义化),选择合适的标签(代码语义化)便于开发者阅读和写出更优雅的代码的同时让浏览器的爬虫和机器很好地解析。 注意: 1.尽可能少的使用无语义的标签div和span; 2.在语义不明显时,既可以使用div或者p时,尽量用p, 因为p在默认情况下有上下间距,对兼容特殊终端有利; 3.不要使用纯样式标签,如:b、font、u等,改用css设置。 4.需要强调的文本,可以包含在strong或者em标签中(浏览器预设样式,能用CSS指定就不用他们),strong默认样式是加粗(不要用b),em是斜体(不用i); 5.使用表格时,标题要用caption,表头用thead,主体部分用tbody包围,尾部用tfoot包围。表头和一般单元格要区分开,表头用th,单元格用td; 6.表单域要用fieldset标签包起来,并用legend标签说明表单的用途; 7.每个input标签对应的说明文本都需要使用label标签,并且通过为input设置id属性,在lable标签中设置for=someld来让说明文本和相对应的input关联起来。
前端达人
2018/10/16
7.6K0
相关推荐
高频js笔试题看这一篇就够了
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文