MySQL学习笔记(十四)索引失效有哪些情况?

news2024/11/22 16:12:37

1.表和数据

CREATE TABLE `t_user` (
  `id` bigint(32) NOT NULL AUTO_INCREMENT,
  `user_name` varchar(40) DEFAULT NULL COMMENT '用户名',
  `user_code` varchar(40) DEFAULT NULL COMMENT '用户编号',
  `phone` varchar(11) DEFAULT NULL COMMENT '电话',
  `age` tinyint(3) DEFAULT NULL COMMENT '年龄',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `update_time` varchar(32) DEFAULT NULL COMMENT '更新时间',
  `address` varchar(100) DEFAULT NULL COMMENT '地址',
  PRIMARY KEY (`id`),
  KEY `idx_create_time` (`create_time`),
  KEY `idx_update_time` (`update_time`),
  KEY `idx_phone` (`phone`) USING BTREE,
  KEY `idx_name_code_add` (`user_name`,`user_code`,`address`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8 COMMENT='用户表';

INSERT INTO `eom`.`t_user` (`id`, `user_name`, `user_code`, `phone`, `age`, `create_time`, `update_time`, `address`) VALUES ('1', '张三', '10021', '18500123322', '22', '2022-12-03 17:17:08', '2022-12-04 17:17:08', '天津市滨海区水利路11号');
INSERT INTO `eom`.`t_user` (`id`, `user_name`, `user_code`, `phone`, `age`, `create_time`, `update_time`, `address`) VALUES ('2', '张龙', '10022', '18500123323', '23', '2022-12-03 17:17:08', '2022-12-01 17:17:08', '北京市海淀区五道口33号');
INSERT INTO `eom`.`t_user` (`id`, `user_name`, `user_code`, `phone`, `age`, `create_time`, `update_time`, `address`) VALUES ('3', '张哥', '10023', '18500123324', '24', '2022-11-03 17:17:08', '2022-12-02 17:17:08', '北京市海淀区五道口33号');
INSERT INTO `eom`.`t_user` (`id`, `user_name`, `user_code`, `phone`, `age`, `create_time`, `update_time`, `address`) VALUES ('4', '张明', '10024', '18500123325', '25', '2022-10-03 17:17:08', '2022-12-03 17:17:08', '北京市海淀区五道口33号');
INSERT INTO `eom`.`t_user` (`id`, `user_name`, `user_code`, `phone`, `age`, `create_time`, `update_time`, `address`) VALUES ('5', '王子', '10025', '18500123326', '26', '2022-12-01 17:17:08', '2022-12-04 17:17:08', '北京市海淀区五道口33号');
INSERT INTO `eom`.`t_user` (`id`, `user_name`, `user_code`, `phone`, `age`, `create_time`, `update_time`, `address`) VALUES ('6', '李明', '10026', '18500123327', '33', '2022-12-02 17:17:08', '2022-11-05 17:17:08', '北京市海淀区五道口33号');
INSERT INTO `eom`.`t_user` (`id`, `user_name`, `user_code`, `phone`, `age`, `create_time`, `update_time`, `address`) VALUES ('7', '陈哥', '10027', '18500123328', '44', '2022-08-03 17:17:08', '2022-10-06 17:17:08', '北京市海淀区五道口33号');
INSERT INTO `eom`.`t_user` (`id`, `user_name`, `user_code`, `phone`, `age`, `create_time`, `update_time`, `address`) VALUES ('8', '刘志', '10028', '18500123329', '55', '2022-07-03 17:17:08', '2022-09-07 17:17:08', '北京市海淀区五道口33号');
INSERT INTO `eom`.`t_user` (`id`, `user_name`, `user_code`, `phone`, `age`, `create_time`, `update_time`, `address`) VALUES ('9', '黄强', '10029', '18500123333', '66', '2022-06-03 17:17:08', '2022-08-08 17:17:08', '北京市海淀区五道口33号');


在这里插入图片描述

2.key_len计算规则

EXPLAIN select * from t_user where user_name = '张龙' 

在这里插入图片描述

user_name 类型为varchar(40),字符集为utf8,也就是使用3个字节来表示一个完整的UTF-8。此时如果这个字段命中索引,key_len = 40* 3 =120;
由于该字段类型varchar为变长数据类型,需要再额外添加2个字节。此时,key_len = 120 + 2 = 122;
由于该字段允许为NULL(default NULL),需要再添加1个字节。此时,key_len = 122 + 1 = 123;

3.最左匹配原则


3.1.不命中的情况

EXPLAIN SELECT * FROM t_user WHERE user_code = '10022' AND address = '北京市海淀区五道口33号'  

在这里插入图片描述

条件里面没有添加user_name,无论剩余2个条件是否添加,或者顺序是否按照索引,只要user_name 没有就无法命中索引,这就是最左匹配

注意这里有个情况,就是覆盖索引的情况,例如上面的sql不用select*,改为下面的

EXPLAIN SELECT user_name,user_code,address FROM t_user WHERE user_code = '10022' AND address = '北京市海淀区五道口33号'  

可以看出,就会命中索引,此时命中的是覆盖索引
在这里插入图片描述

3.2.命中的情况

  • 按照索引顺序3个添加都加上,此时看key_len的长度是3个字段都命中了
EXPLAIN select * from t_user where user_name = '张龙' and user_code = '10022' and address = '北京市'

在这里插入图片描述

  • 按照索引顺序只添加前面2个条件,只命中了前面2个字段
EXPLAIN select * from t_user where user_name = '张龙' and user_code = '10022' 

在这里插入图片描述

  • 把顺序打乱,发现还是会命中索引,而且3个字段都命中了,这是因为MySQL优化器会把顺序优化成索引的顺序
EXPLAIN SELECT * FROM t_user WHERE address = '北京市海淀区五道口33号' AND user_code = '10022' AND user_name = '张龙'

在这里插入图片描述

总结,只要有user_name字段就会命中索引,不管后面那2个条件是否有,或者是否按照索引顺序,都会命中索引的,只不过key_len长度不同

4.索引列参与运算

EXPLAIN SELECT * FROM t_user where id + 1 = 2

如图主键id+1=2就不会命中索引,这种情况改成where id = 2 - 1就会命中主键索引
在这里插入图片描述

5.索引列使用函数

EXPLAIN SELECT * FROM t_user where SUBSTR(phone,1,3) = '100';

如图phone这个字段有索引,如果使用函数的话就会失效,全表扫描
在这里插入图片描述

6.like %xxx%

EXPLAIN SELECT * FROM t_user where phone like '%100%';

如图like模糊匹配左右2边都是% 会索引失效,但是如果改成100%就会命中索引
在这里插入图片描述

7.字段类型转换

EXPLAIN SELECT * FROM t_user where phone = 100

如图,phone是varchar类型,但是where 条件是=100,变成int型了,phone就会转化成int型,字段的类型就变了,就变成全表扫描了
在这里插入图片描述

但是有种情况是例外,就是int型=字符串,此时MySQL会把’1’转换成int型,所以就会命中索引

EXPLAIN SELECT * FROM t_user where id = '1'

在这里插入图片描述

8.日期类型like

EXPLAIN SELECT * FROM t_user where create_time like '2022-12-03%'

日期类型,datetime,date如果使用like是不会走索引的,因为字段类型不一样,这实际上跟上面的字段转换是同一个问题
在这里插入图片描述

9.or操作

EXPLAIN SELECT * FROM t_user where phone = '111' or address = '222'

如图,or前后有2个条件,phone 是有索引,address 没有所索引,这会导致索引失效,全表扫描
在这里插入图片描述

而如果or前后都是索引字段,phone和update_time 都是索引字段,就会命中索引,如下

EXPLAIN SELECT * FROM t_user where phone = '111' or update_time = '222'

在这里插入图片描述

10.is not null

EXPLAIN SELECT * FROM t_user where phone is not null

is not null不会走索引,is null可以命中索引
在这里插入图片描述

11.not in

EXPLAIN SELECT * FROM t_user where phone not in ('11','22')

in 会走索引,not in 不会走索引
在这里插入图片描述

但是有个例外情况就是如果换成主键id,就会走索引

EXPLAIN SELECT * FROM t_user where id not in (1,2)

在这里插入图片描述

12.order by

EXPLAIN SELECT * FROM t_user ORDER BY phone

order by 普通索引会失效
在这里插入图片描述

这里如果不用select * ,直接查字段会走覆盖索引

EXPLAIN SELECT phone FROM t_user ORDER BY phone

在这里插入图片描述

但是如果换成order by id,主键索引会命中

EXPLAIN SELECT * FROM t_user ORDER BY id

在这里插入图片描述

13.不等于

EXPLAIN SELECT * FROM t_user where  phone != '11'
EXPLAIN SELECT * FROM t_user where  phone <> '11'

在这里插入图片描述

不等于不会走索引,但是主键索引,和覆盖索引会走索引,这2个情况是例外

14.其他情况

当全表扫描速度比索引速度快时,mysql会使用全表扫描,此时索引失效。也就是说,当Mysql发现通过索引扫描的行记录数超过全表的10%-30%时,优化器可能会放弃走索引,自动变成全表扫描。某些场景下即便强制SQL语句走索引,也同样会失效。

类似的问题,在进行范围查询(比如>、< 、>=、<=、in等条件)时往往会出现上述情况,而上面提到的临界值根据场景不同也会有所不同。

15.索引的规范使用

索引是提高数据库查询性能的一个重要方法。

使用索引用可快速找出某个列中包含特定值的行。不使用索引,必须从第一条记录开始读,可能要读完整个表,才能找出相关的行。

使用索引就像查字典一样,我们可以根据拼音、笔画、偏旁部首等排序的目录(索引),快速查找到需要的字。

下面总结了一些规范建议,可以用来参考,并非绝对真理。

  • 单表的索引数建议不超过5个,组合索引的字段原则上不超过3个。

  • 尽量不要在较长字符串的字段上建立索引,可以设置索引字段前缀长度。

  • 选择在查询过滤中使用率较高,如where,orderby,group by的列建立索引。

  • 不要在区分度不高的列上建立索引,比如性别等,利用不了索引性能。

  • 不要在经常更新的列上建立索引,数据更新也会更新索引,影响数据库性能。

  • 建立组合索引时,区分度最高,或者查询频率最高的,放在最左侧。

  • 合理利用覆盖索引来满足查询要求,避免回表查询,减少I/O开销。

  • 删除不再使用、少使用、或者重复的索引,减少数据更新的开销。

  • 利用explain来判断查询语句,是使用了索引,还是走了全表扫描。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/65943.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

微机----------------中断技术

目录 中断概述中断处理过程中断请求中断响应中断处理8086/8088中断中断类型中断优先级顺序⭐中断向量表中断处理过程中断概述 中断: 当CPU执行程序时,由于随机的事件引起CPU暂时停止正在执行的程序,而转去执行中断服务程序,处理完后又返回被终止的程序断点处继续执行,这个…

Bug系列路径规划算法原理介绍(四)——I-BUG 算法

本系列文章主要对Bug类路径规划算法的原理进行介绍&#xff0c;在本系列的第一篇文章中按照时间顺序梳理了自1986年至2018年Bug类路径规划算法的发展&#xff0c;整理了13种BUG系列中的典型算法&#xff0c;从本系列的第二篇文章开始依次详细介绍了其中具有代表性的BUG1、BUG2、…

数学基础从高一开始2、集合间的基本关系

高中数学人教 A 版必修一 集合间的基本关系 学习目标&#xff1a; (1)初步理解集合之间的包含与相等的含义; (2)能识别给定集合的子集和真子案&#xff0c;了解空集含义: (3)能进行自然语言、图形语言(Venn 图)、符号语言闻的转换&#xff0c;积萦抽象思维的经验&#xff0c; …

递归算法(及其衍生算法:缓存,分治,回溯)

文章目录一、初识递归二、缓存三、分治四、回溯一、初识递归 递归函数 终止条件 递归关系 终止条件&#xff1a; 当大问题被拆解成能轻松解决的小问题时&#xff0c;运行终止条件中的逻辑 递归关系&#xff1a; 定义如何将大问题拆解为小问题 例子&#xff1a;小名跑步。 …

这十一个副业在家就可以完成,疫情在家也有收入,建议收藏

2022年&#xff0c;谁还没有副业&#xff1f; 经过两年的疫情&#xff0c;我们都知道没有钱是一件非常不舒服的事情。现在的做法是&#xff1a;主营业务要求稳定&#xff0c;副业要求发展&#xff1b;好好发展副业是硬道理。 在过去的两年里&#xff0c;我一直在探索副业项目…

(六)Vue之数据代理

文章目录回顾Object.defineProperty方法数据属性valueenumerablewritableconfigurable访问器属性get()set(v: any)何为数据代理Vue中的数据代理Vue学习目录上一篇&#xff1a;&#xff08;六&#xff09;Vue之MVVC 回顾Object.defineProperty方法 Object.defineProperty方法的…

Chain Surfase Test - java 链表经典 OJ 面试题 - 巨细

效果图 LeetCode - 206. 反转链表 代码如下&#xff1a; /** Definition for singly-linked list. public class ListNode { int val;ListNode next;ListNode() {}ListNode(int val) { this.val val; }ListNode(int val, ListNode next) { this.val val; this.next next; …

K-Means++代码实现

K-Means代码实现 数据集 https://download.csdn.net/download/qq_43629083/87246495 import pandas as pd import numpy as np import random import math %matplotlib inline from matplotlib import pyplot as plt# 按文件名读取整个文件 data pd.read_csv(data.csv)class…

Minikube – 配置 Jenkins Kubernetes plugin

文章目录1. 配置 kubernetes credentials2. 安装 kubernets plugin3. 安装 docker 插件4. 连接 minikube 集群5. Pod template 参数6. Container template 参数7. 实例7.1 创建一个简单 pod7.2 pod name 变化7.3 指定 namespace7.4 volumes 挂载7.5 Liveness Probe 探针7.6 创建…

关于l2实时接口的功能分析

因为国内外股价的上涨都可以在界面上去查询&#xff0c;所以公司能准确地判断股价上涨&#xff0c;并适时买入、卖出&#xff0c;以此获得一定的利润。 l2实时接口还可以把以往的数据表示成一条折线&#xff0c;让公司在进行分析时更形象、更有参考意义。在连接界面后&#xf…

[附源码]Python计算机毕业设计Django校园订餐系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

星环科技TDS 2.4.0 发布: 数据开发、数据治理、数据运营套件能力再次升级

近日&#xff0c;星环科技大数据开发工具 Transwarp Data Studio 2.4.0版本重磅发布&#xff0c;新版本中数据开发、数据治理、数据运营三大套件能力全部升级&#xff0c;让数据开发更便捷、数据治理更高效、数据运营更智能。本次升级的核心能力如下&#xff1a; 数据开发套件…

【Opencv实战】高手勿入,Python使用Opencv+Canny实现边缘检测以及轮廓检测(详细步骤+源码分享)

前言 有温度 有深度 有广度 就等你来关注哦~ 所有文章完整的素材源码都在&#x1f447;&#x1f447; 粉丝白嫖源码福利&#xff0c;请移步至CSDN社区或文末公众hao即可免费。 在这次的案例实战中&#xff0c;我们将使用Python 3和OpenCV。我们将使用OpenCV&#xff0c;因为它是…

谷歌牛人发布小说式《算法图解》,竟被人扒下来,在GitHub开源了

今天给大家带来了一本算法方向的好书&#xff1a;巴尔加瓦&#xff08;Aditya Bhargava&#xff09;老师 著&#xff0c;袁国忠老师译的 《算法图解&#xff1a;像小说一样有趣的算法入门书》&#xff0c;网上有没有开源版本我不知道&#xff0c;我就看他内容不错所以推荐给大家…

蓄电池建模、分析与优化(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️❤️&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清…

[附源码]Python计算机毕业设计Django校园运动会管理系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

数据存储,详细讲解

✨数据存储&#xff0c;详细讲解&#x1f49c;数据类型的介绍&#xff1a;&#x1f499;整形的内存存储大小端介绍&#xff1a;&#x1f49b;浮点数的存储&#x1f49c;数据类型的介绍&#xff1a; 1.内置类型&#xff1a; char //字符数据类型&#xff08;1&#xff…

SpringBoot 之 AOP

前言&#xff1a; Spring 三大核心思想是啥&#xff0c;还记得不&#xff1f;IOC&#xff08;控制反转&#xff09;&#xff0c;DI&#xff08;依赖注入&#xff09;&#xff0c;AOP&#xff08;面向切面编程&#xff09;。回顾一下这三个东西&#xff1a; IOC&#xff1a;不考…

Dash初探:如何将Label和Dropdown放在一行

Use Dash! How to display html.Lable and dcc.Dropdown on the same line? 1、目标 下图展示了我想要实现的效果。 数据筛选部分包含了三个筛选条件&#xff1a;日期区间选择器&#xff1b;区域选择器&#xff1b;地市选择器。其中&#xff0c;地市选择器的取值和已选区域…

【1805. 字符串中不同整数的数目】

来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 描述&#xff1a; 给你一个字符串 word &#xff0c;该字符串由数字和小写英文字母组成。 请你用空格替换每个不是数字的字符。例如&#xff0c;"a123bc34d8ef34" 将会变成 " 123 34 8 34" 。注意…