浅谈mysql哪些情况会导致索引失效


Posted in MySQL onNovember 20, 2021

下面有一些培训教学机构的口诀和我个人的一些总结:
为了讲解以下索引内容,我们先建立一个临时的表 test02

CREATE TABLE `sys_user` (
  `id` varchar(64) NOT NULL COMMENT '主键',
  `name` varchar(64) DEFAULT NULL COMMENT '名字',
  `age` int(64) DEFAULT NULL COMMENT '年龄',
  `pos` varchar(64) DEFAULT NULL COMMENT '职位',
  PRIMARY KEY (`id`),
  KEY `idx_sys_user_nameAgePos` (`name`,`age`,`pos`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';

这个表有四个字段 主键 、名字、年龄、职位

下面我们来讲解第一个口诀:
1.全值匹配我最爱
2.最佳左前缀法则(重要)

全值匹配意思就是联立的复合索引的顺序和个数要和检索的条件顺序和个数相同。
最佳左前缀法则是指,如果索引了多列,要遵守最左前缀法则。指的是查询从索引的最左前列开始并且不跳过索引中的列
下面我们给这个表建立一个复合索引

ALTER TABLE sys_user ADD INDEX idx_sys_user_nameAgePos(name,age,pos);

以下是我们的检索语句:

SELECT * FROM sys_user WHERE name='小明' AND age = 22 AND pos ='java';

浅谈mysql哪些情况会导致索引失效

我们通过在检索语句前面加关键字 EXLAIN,可以知道是否使用的索引

(1)EXPLAIN SELECT * FROM sys_user WHERE name='小明' AND age = 22 AND pos ='java';
(2)EXPLAIN SELECT * FROM sys_user WHERE name='小明' AND age = 22 ;
(3)EXPLAIN SELECT * FROM sys_user WHERE name='小明'  AND pos ='java';

浅谈mysql哪些情况会导致索引失效

浅谈mysql哪些情况会导致索引失效

浅谈mysql哪些情况会导致索引失效

通过展示的结果我们可以知道,第一个复合索引的三个字段我们都用了,第二个复合索引我们只用到两个字段,第三个复合索引我们只用到一个字段。三个语句我们都用到索引,显然第一种是最优的。

我们再看看哪种情况会失效:

(4)EXPLAIN SELECT * FROM sys_user WHERE age = 22;
(5)EXPLAIN SELECT * FROM sys_user WHERE pos ='java';
(6)EXPLAIN SELECT * FROM sys_user WHERE age = 22 AND pos ='java';

浅谈mysql哪些情况会导致索引失效

浅谈mysql哪些情况会导致索引失效

浅谈mysql哪些情况会导致索引失效

以上三种情况都变成了全表扫描,原因是违反了最左左前缀原则,因为复合索引最左边的是name,当检索条件name没在前面索引将失效,第一种情况满足了全值匹配,第二种满足了两个字段name和age,第三种因为只满足了name,所以索引只用到name。

3.不在索引列上做任何操作(计算、函数(自动或手动)类型转换),会使索引失效转为全表扫描

(7)EXPLAIN SELECT * FROM sys_user WHERE  LEFT(name,1)='小明';

浅谈mysql哪些情况会导致索引失效

第七种情况失效是因为索引列做了计算或者函数的操作,导致了全表扫描。

4.存储引擎不能使用索引中范围条件右边的列
可能大家关看上面的文字不知道是什么意思,下面我们执行一下查询语句就清楚了

(8)EXPLAIN SELECT * FROM sys_user WHERE name='小明' AND age < 22 AND pos ='java';

浅谈mysql哪些情况会导致索引失效

从上图我们可以知道type变成了范围级别,也就是说age<22之后的pos字段的索引失效了。

5.尽量使用覆盖索引(只访问索引的查询(索引列和查询列一致),减少select * 的使用
这个就是字面意思,查询具体的字段比查询*效率更高,下面我们坐一下对比

(9)EXPLAIN SELECT * FROM sys_user WHERE name='小明' AND age =22 AND pos ='java';
(10)EXPLAIN SELECT name,age,pos FROM sys_user WHERE name='小明' AND age =22 AND pos ='java';

浅谈mysql哪些情况会导致索引失效

浅谈mysql哪些情况会导致索引失效

6.mysql在使用不等于(!= 或者<>)的时候无法使用索引会导致全表扫描
(!= 或者<>)通常会匹配到大量数据,当使用索引的花销大于全表扫描时,mysql则会放弃使用索引而选择全表扫描

(11)EXPLAIN SELECT * FROM sys_user WHERE name !='小明'

浅谈mysql哪些情况会导致索引失效

结果显示索引失效导致了全表扫描

7.is null,is not null 也无法使用索引
is null,is not null 通常会匹配到大量数据,当使用索引的花销大于全表扫描时,mysql则会放弃使用索引而选择全表扫描

(12)EXPLAIN SELECT * FROM sys_user WHERE name is not null

浅谈mysql哪些情况会导致索引失效

8.like以通配符开头('%abc…')mysql索引会失效变成全表扫描的操作,(%写右边则可以避免索引失效,如果业务实在需要'%abc…%'则可以用覆盖索引避免索引失效)

(13)EXPLAIN SELECT * FROM sys_user WHERE name like '%明%'
(14)EXPLAIN SELECT * FROM sys_user WHERE name like '明%'
(15)EXPLAIN SELECT name,age,pos FROM sys_user WHERE name like '%明%'

浅谈mysql哪些情况会导致索引失效

浅谈mysql哪些情况会导致索引失效

浅谈mysql哪些情况会导致索引失效

从上面的结果,第一种索引失效,第二种只写右边的%则可以避免索引失效,第三种如果业务实在需要‘%abc…%'这种sql,则可以用覆盖索引解决索引失效的问题

9.字符串不加单引号索引会失效

(16)EXPLAIN SELECT * FROM sys_user WHERE name=222;

浅谈mysql哪些情况会导致索引失效

因为检索字符串是必须加单引号,上面用用了222是int类型,mysql在检索的时候会判断name是varchar的类型会将222转换为'222'进行检索,索引列发生了类型转换,故索引失效。

10.少用or,用它连接时会索引失效

(16)EXPLAIN SELECT * FROM sys_user WHERE name='小明' or age = 22;

浅谈mysql哪些情况会导致索引失效

到此这篇关于浅谈mysql哪些情况会导致索引失效的文章就介绍到这了,更多相关mysql 索引失效内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

MySQL 相关文章推荐
MySQL sql_mode修改不生效的原因及解决
May 07 MySQL
MYSQL(电话号码,身份证)数据脱敏的实现
May 28 MySQL
带你学习MySQL执行计划
May 31 MySQL
新手入门Mysql--sql执行过程
Jun 20 MySQL
MySQL连表查询分组去重的实现示例
Jul 01 MySQL
MySQL 数据类型详情
Nov 11 MySQL
MySQL和Oracle批量插入SQL的通用写法示例
Nov 17 MySQL
教你使用VS Code的MySQL扩展管理数据库的方法
Jan 22 MySQL
MySQL创建管理HASH分区
Apr 13 MySQL
Mysql 8.x 创建用户以及授予权限的操作记录
Apr 18 MySQL
mysql 8.0.27 绿色解压版安装教程及配置方法
Apr 20 MySQL
Mysql数据库事务的脏读幻读及不可重复读详解
May 30 MySQL
MySQL数据库索引的最左匹配原则
Nov 20 #MySQL
mysql 联合索引生效的条件及索引失效的条件
Nov 20 #MySQL
MySQL利用UNION连接2个查询排序失效详解
Nov 20 #MySQL
浅谈MySql整型索引和字符串索引失效或隐式转换问题
Nov 20 #MySQL
mysql5.7的安装及Navicate长久免费使用的实现过程
MySQL中order by的使用详情
Nov 17 #MySQL
关于MySQL中的 like操作符详情
Nov 17 #MySQL
You might like
main.php
2006/12/09 PHP
PHP 长文章分页函数 带使用方法,不会分割段落,翻页在底部
2009/10/22 PHP
PHP调用wsdl文件类型的接口代码分享
2014/11/19 PHP
typecho插件编写教程(一):Hello World
2015/05/28 PHP
php编程实现简单的网页版计算器功能示例
2017/04/26 PHP
Thinkphp5 自定义上传文件名的实现方法
2019/07/23 PHP
php实例化一个类的具体方法
2019/09/19 PHP
[原创]静态页面也可以实现预览 列表不同的显示方式
2006/10/14 Javascript
基于jquery的一行代码轻松实现拖动效果
2010/12/28 Javascript
JavaScript中使用arguments获得函数传参个数实例
2014/08/27 Javascript
js获取浏览器基本信息大全
2014/11/27 Javascript
javascript使用shift+click实现选择和反选checkbox的方法
2015/05/04 Javascript
在Linux系统中搭建Node.js开发环境的简单步骤讲解
2016/01/26 Javascript
Js类的静态方法与实例方法区分及jQuery拓展的两种方法
2016/06/03 Javascript
js不间断滚动的简单实现
2016/06/03 Javascript
通过jsonp获取json数据实现AJAX跨域请求
2017/01/22 Javascript
jQuery实现form表单序列化转换为json对象功能示例
2018/05/23 jQuery
详解Vue微信授权登录前后端分离较为优雅的解决方案
2018/06/29 Javascript
nodejs同步调用获取mysql数据时遇到的大坑
2019/03/02 NodeJs
Element InfiniteScroll无限滚动的具体使用方法
2020/07/27 Javascript
用Javascript实现发送短信验证码间隔功能
2021/02/08 Javascript
[00:17]DOTA2荣耀之路5:It’s a disastah!
2018/05/28 DOTA
Python列表推导式的使用方法
2013/11/21 Python
基于python yield机制的异步操作同步化编程模型
2016/03/18 Python
python利用高阶函数实现剪枝函数
2018/03/20 Python
python算法与数据结构之冒泡排序实例详解
2019/06/22 Python
python+pygame实现坦克大战
2019/09/10 Python
python 3.7.4 安装 opencv的教程
2019/10/10 Python
详解Django配置优化方法
2019/11/18 Python
使用Python爬虫库requests发送请求、传递URL参数、定制headers
2020/01/25 Python
如何用Python 加密文件
2020/09/10 Python
Auchan Direct波兰:欧尚在线杂货店
2016/10/19 全球购物
GafasWorld西班牙:购买太阳镜、眼镜和隐形眼镜
2019/09/08 全球购物
国外软件测试工程师面试题
2016/12/09 面试题
MySQL索引知识的一些小妙招总结
2021/05/10 MySQL
详解MySQL的主键查询为什么这么快
2022/04/03 MySQL