MySQL-索引详解(五)

news2024/11/25 0:42:09

♥️作者:小刘在C站

♥️个人主页: 小刘主页 

♥️努力不一定有回报,但一定会有收获加油!一起努力,共赴美好人生!

♥️学习两年总结出的运维经验,以及思科模拟器全套网络实验教程。专栏:云计算技术

♥️小刘私信可以随便问,只要会绝不吝啬,感谢CSDN让你我相遇!

前言

本次MySQL—索引章节比较多,分为多篇进行发布,本章继续,链接—上一章

目录

6.5 SQL提示

索引情况如下:

 6.6 覆盖索引

6.7 前缀索引

1). 语法

示例:

 2). 前缀长度

3). 前缀索引的查询流程

6.8 单列索引与联合索引

7.索引设计原则


6.5 SQL提示

目前 tb_user 表的数据情况如下 :

 

索引情况如下:

 把上述的 idx_user_age, idx_email 这两个之前测试使用过的索引直接删除。

drop index idx_user_age on tb_user;
drop index idx_email on tb_user;
A. 执行 SQL : explain select * from tb_user where profession = ' 软件工程 ';

 查询走了联合索引。

B. 执行 SQL ,创建 profession 的单列索引: create index idx_user_pro on
tb_user(profession)

 C. 创建单列索引后,再次执行A中的SQL语句,查看执行计划,看看到底走哪个索引。

测试结果,我们可以看到, possible_keys idx_user_pro_age_sta,idx_user_pro 这两个
索引都可能用到,最终 MySQL 选择了 idx_user_pro_age_sta 索引。这是 MySQL 自动选择的结果。

那么,我们能不能在查询的时候,自己来指定使用哪个索引呢? 答案是肯定的,此时就可以借助于 MySQL SQL 提示来完成。 接下来,介绍一下 SQL 提示。

SQL 提示,是优化数据库的一个重要手段,简单来说,就是在 SQL 语句中加入一些人为的提示来达到优化操作的目的。
1). use index : 建议 MySQL 使用哪一个索引完成此次查询(仅仅是建议, mysql 内部还会再次进
行评估)。

explain select * from tb_user use index(idx_user_pro) where profession = '软件工
程';
2). ignore index : 忽略指定的索引。
explain select * from tb_user ignore index(idx_user_pro) where profession = '软件工
程';
3). force index : 强制使用索引。
explain select * from tb_user force index(idx_user_pro) where profession = '软件工
程';
示例演示:
A. use index
explain select * from tb_user use index(idx_user_pro) where profession = '软件工
程';

 B. ignore index

explain select * from tb_user ignore index(idx_user_pro) where profession = '软件工
程';

 C. force index

explain select * from tb_user force index(idx_user_pro_age_sta) where profession =
'软件工程';

 6.6 覆盖索引

尽量使用覆盖索引,减少 select * 。 那么什么是覆盖索引呢? 覆盖索引是指 查询使用了索引,并
且需要返回的列,在该索引中已经全部能够找到 。

接下来,我们来看一组 SQL 的执行计划,看看执行计划的差别,然后再来具体做一个解析。

explain select id, profession from tb_user where profession = '软件工程' and age =
31 and status = '0' ;
explain select id,profession,age, status from tb_user where profession = '软件工程'
and age = 31 and status = '0' ;
explain select id,profession,age, status, name from tb_user where profession = '软
件工程' and age = 31 and status = '0' ;
explain select * from tb_user where profession = '软件工程' and age = 31 and status
= '0';

上述这几条SQL的执行结果为:

 

从上述的执行计划我们可以看到,这四条 SQL 语句的执行计划前面所有的指标都是一样的,看不出来差异。但是此时,我们主要关注的是后面的 Extra ,前面两天 SQL 的结果为 Using where; Using
Index ; 而后面两条 SQL 的结果为 : Using index condition

 因为,在tb_user表中有一个联合索引 idx_user_pro_age_sta,该索引关联了三个字段

profession age status ,而这个索引也是一个二级索引,所以叶子节点下面挂的是这一行的主键 id 。 所以当我们查询返回的数据在 id profession age status 之中,则直接走二级索引 直接返回数据了。 如果超出这个范围,就需要拿到主键 id,再去扫描聚集索引,再获取额外的数据 了,这个过程就是回表。 而我们如果一直使用 select * 查询返回所有字段值,很容易就会造成回表 查询(除非是根据主键查询,此时只会扫描聚集索引)。
为了大家更清楚的理解,什么是覆盖索引,什么是回表查询,我们一起再来看下面的这组 SQL 的执行过程。
A. 表结构及索引示意图 :

 

 

id 是主键,是一个聚集索引。 name 字段建立了普通索引,是一个二级索引(辅助索引)。

B. 执行 SQL : select * from tb_user where id = 2;

 

根据 id 查询,直接走聚集索引查询,一次索引扫描,直接返回数据,性能高。

C. 执行 SQL selet id,name from tb_user where name = 'Arm';

 

虽然是根据 name 字段查询,查询二级索引,但是由于查询返回在字段为 id name ,在 name 的二级索引中,这两个值都是可以直接获取到的,因为覆盖索引,所以不需要回表查询,性能高。
D. 执行 SQL selet id,name,gender from tb_user where name = 'Arm';

 

由于在 name 的二级索引中,不包含 gender ,所以,需要两次索引扫描,也就是需要回表查询,性能相较差一点。 

6.7 前缀索引

当字段类型为字符串( varchar text longtext 等)时,有时候需要索引很长的字符串,这会让
索引变得很大,查询时,浪费大量的磁盘 IO , 影响查询效率。此时可以只将字符串的一部分前缀,建立索引,这样可以大大节约索引空间,从而提高索引效率。

1). 语法

create index idx_xxxx on table_name(column(n)) ;

示例:

tb_user 表的 email 字段,建立长度为 5 的前缀索引。
create index idx_email_5 on tb_user(email(5)); 1

 2). 前缀长度

可以根据索引的选择性来决定,而选择性是指不重复的索引值(基数)和数据表的记录总数的比值,索引选择性越高则查询效率越高, 唯一索引的选择性是 1 ,这是最好的索引选择性,性能也是最好的。
select count(distinct email) / count(*) from tb_user ;
select count(distinct substring(email,1,5)) / count(*) from tb_user ;

3). 前缀索引的查询流程

 

6.8 单列索引与联合索引

单列索引:即一个索引只包含单个列。
联合索引:即一个索引包含了多个列。
我们先来看看 tb_user 表中目前的索引情况 :
在查询出来的索引中,既有单列索引,又有联合索引。
接下来,我们来执行一条 SQL 语句,看看其执行计划:

 

通过上述执行计划我们可以看出来,在 and 连接的两个字段 phone name 上都是有单列索引的,但是最终 mysql 只会选择一个索引,也就是说,只能走一个字段的索引,此时是会回表查询的。
紧接着,我们再来创建一个 phone name 字段的联合索引来查询一下执行计划。
create unique index idx_user_phone_name on tb_user(phone,name);

此时,查询时,就走了联合索引,而在联合索引中包含 phone name 的信息,在叶子节点下挂的是对应的主键 id ,所以查询是无需回表查询的。
此时,查询时,就走了联合索引,而在联合索引中包含 phone name 的信息,在叶子节点下挂的是对应的主键 id ,所以查询是无需回表查询的。
如果查询使用的是联合索引,具体的结构示意图如下:

 

7.索引设计原则

1). 针对于数据量较大,且查询比较频繁的表建立索引。
2). 针对于常作为查询条件( where )、排序( order by )、分组( group by )操作的字段建立索引。
3). 尽量选择区分度高的列作为索引,尽量建立唯一索引,区分度越高,使用索引的效率越高。
4). 如果是字符串类型的字段,字段的长度较长,可以针对于字段的特点,建立前缀索引。
5). 尽量使用联合索引,减少单列索引,查询时,联合索引很多时候可以覆盖索引,节省存储空间, 避免回表,提高查询效率。
6). 要控制索引的数量,索引并不是多多益善,索引越多,维护索引结构的代价也就越大,会影响增 删改的效率。
7). 如果索引列不能存储 NULL 值,请在创建表时使用 NOT NULL 约束它。当优化器知道每列是否包含NULL 值时,它可以更好地确定哪个索引最有效地用于查询。
好啦,MySQL索引就到此结束啦
投票

♥️关注,就是我创作的动力

♥️点赞,就是对我最大的认可

♥️这里是小刘,励志用心做好每一篇文章,谢谢大家

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

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

相关文章

【K8S系列】深入解析k8s网络之—网络故障

序言 你只管努力,其他交给时间,时间会证明一切。 文章标记颜色说明: 黄色:重要标题红色:用来标记结论绿色:用来标记一级论点蓝色:用来标记二级论点 Kubernetes (k8s) 是一个容器编排平台&#x…

FasterTransformer 005 初始化:如何将参数传给模型?

cpp的例子 device_malloc cpp没有用具体数值初始化 float *d_from_tensor NULL;device_malloc(&d_from_tensor, batch_size * seq_len * hidden_dim);https://github1s.com/NVIDIA/FasterTransformer/blob/v1.0/sample/cpp/transformer_fp32.cc#L35-L38 直接用的cudaMal…

【电子学会】2023年03月图形化四级 -- 绘制直尺

绘制直尺 编写一段程序,绘制一段7厘米的直尺。 1. 准备工作 (1)保留小猫角色,隐藏; (2)白色背景。 2. 功能实现 (1)点击绿旗,设置笔的颜色为红色&#…

事务和事务的隔离级别

一、事务 (一)为什么需要事务 事务是数据库管理系统(DBMS)执行过程中的一个逻辑单位(不可再进行分割),由一个有限的数据库操作序列构成(多个DML语句,select语句不包含事…

数字图像处理期末复习习题 SCUEC part1

1.在利用LoG算子做边缘检测的时候,作为一种经验法则,当滤波器空间参数为a7时,LoG滤波器空域模板大小应为 答:4343 理由是:n大于等于6a1 2.空间域方法主要分为灰度变换和空间滤波两类,灰度变换在图像的单…

【前端 - CSS】第 15 课 - 复合选择器

欢迎来到博主 Apeiron 的博客,祝您旅程愉快 ! 时止则止,时行则行。动静不失其时,其道光明。 目录 1、缘起 2、复合选择器 2.1、后代选择器 2.2、子代选择器 2.3、并集选择器 2.4、交集选择器(了解&#xff09…

SpringBatch从入门到实战(三):父子Job和多步骤控制

一:Job嵌套 Job之前也可以嵌套,比如一个父Job封装多个已经存在的子Job。 Configuration public class ChildrenJobConfig {Autowiredprivate JobBuilderFactory jobBuilderFactory;Autowiredprivate StepBuilderFactory stepBuilderFactory;Beanpublic…

基础知识学习---牛客网C++面试宝典(八)操作系统--第三节

1、本栏用来记录社招找工作过程中的内容,包括基础知识学习以及面试问题的记录等,以便于后续个人回顾学习; 暂时只有2023年3月份,第一次社招找工作的过程; 2、个人经历: 研究生期间课题是SLAM在无人机上的应…

Golang每日一练(leetDay0096) 添加运算符、移动零

目录 282. 给表达式添加运算符 Expression Add Operators 🌟🌟🌟 283. 移动零 Move Zeroes 🌟 🌟 每日一练刷题专栏 🌟 Rust每日一练 专栏 Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 …

Cenos7 --- Redis下载和安装(Linux版本)

1.下载和安装 Download | Redis进入官网Download | Redis, 上边点击下载7.0.11,右键复制下载衔接 https://download.redis.io/releases/redis-7.0.2.tar.gz 1.weget获取 我这个安装包放在 /tools/installbags下 cd /tools/installbags wget https://download.red…

Java进阶 —— Java多线程编程笔记

❤ 作者主页:欢迎来到我的技术博客😎 ❀ 个人介绍:大家好,本人热衷于Java后端开发,欢迎来交流学习哦!( ̄▽ ̄)~* 🍊 如果文章对您有帮助,记得关注、点赞、收藏、…

【头歌-Python】9.3 中英文词云绘制(project) 第1~3关

第1关:词云练习1 任务描述 本关任务:编写一个能制作词云的小程序。 相关知识 词云 词云,也叫文字云,是一种应用广泛的数据可视化方法。是过滤掉文本中大量的低频信息,形成“关键词云层”或“关键词渲染”&#xf…

基于VMWare组件安装Centos7.9

1.前提条件 使用VMware进行安装,VMware可以自行下载,需要介质(VMware和CentOS7.9)的同仁,请留言,我给你下载链接。 2.CentOS7.9安装 1.打开VMware,点击“新建虚拟机(N)...” 2.选择“典型” ,点击“下一步…

基础知识学习---牛客网C++面试宝典(六)操作系统--第一节

1、本栏用来记录社招找工作过程中的内容,包括基础知识学习以及面试问题的记录等,以便于后续个人回顾学习; 暂时只有2023年3月份,第一次社招找工作的过程; 2、个人经历: 研究生期间课题是SLAM在无人机上的应…

A100 GPU服务器安装GPU驱动教程

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

【OpenCV DNN】Flask 视频监控目标检测教程 06

欢迎关注『OpenCV DNN Youcans』系列,持续更新中 【OpenCV DNN】Flask 视频监控目标检测教程 06 3.6 OpenCVFlask实时监控和视频播放cvFlask06 项目的文件树cvFlask06 项目的程序文件cvFlask06 项目的网页模板cvFlask06 项目的运行 本系列从零开始,详细…

chatgpt赋能python:Python排序算法实现及其应用

Python排序算法实现及其应用 排序是计算机科学中最基础也是最常用的算法之一。在数据分析、数据挖掘和机器学习等领域,排序算法有着广泛的应用。Python作为一种流行的编程语言,在排序方面具有一定的优势。本文将介绍一些常见的Python排序算法实现以及应…

有趣的图(三)(57)

小朋友们好,大朋友们好! 我是猫妹,一名爱上Python编程的小学生。 和猫妹学Python,一起趣味学编程。 今日主题 咱们之前分别学习了图的基本概念,和图的深度优先遍历算法dfs。 你学会了吗? 咱们今天要学…

Linux系统的tty架构及UART驱动详解

​一、模块硬件学习 1.1. Uart介绍 通用异步收发传输器(Universal Asynchronous Receiver/Transmitter),通常称为UART,是一种异步收发传输器,是电脑硬件的一部分。它将要传输的资料在串行通信与并行通信之间加以转换。 作为把并…

面试问题总结----C/C++部分

1、本栏用来记录社招找工作过程中的内容,包括基础知识学习以及面试问题的记录等,以便于后续个人回顾学习; 暂时只有2023年3月份,第一次社招找工作的过程; 2、个人经历: 研究生期间课题是SLAM在无人机上的应用,有接触SLAM、Linux、ROS、C/C++、DJI OSDK等; 3、参加工作后…