MySQL 索引你必须知道的那些事

news2024/9/21 12:29:14

MySQL 索引你必须知道的那些事

    • 一、什么是索引?
    • 二、索引相关命令演示
    • 三、添加索引的条件
    • 四、索引失效的几种情况
    • 五、索引背后的数据结构
      • 1、概述
      • 2、B树
      • 3、B+树
      • 4、如果一个表中有多个索引(回表现象)

一、什么是索引?

索引是在数据库表的字段上添加的,是为了提高查询效率存在的一种机制。一张表的一个字段可以添加一个索引,当然,多个字段联合起来也可以添加索引。索引相当于一本书的目录,是为了缩小扫描范围而存在的一种机制。

对于一本字典来说,查找某个汉字有两种方式:

(1)第一种方式:一页一页挨着找,直到找到为止,这种查找方式属于全字典扫描。效率比较低。

(2)第二种方式:先通过目录(索引)去定位一个大概的位置,然后直接定位到这个位置,做局域性扫描,缩小扫描的范围,快速的查找。这种查找方式属于通过索引检索,效率较高。

二、索引相关命令演示

以下索引操作均针对下表:

create table student(
	SID int primary key,
	SNAME varchar(255),
	SLOC varchar(255)
);

创建索引
create index 索引名 on 表名(字段名);

create index student_sname_index on student(sname);

给student表的sname字段添加索引,起名:student_sname_index


查看索引
show index from 表名;

show index from student;

查看student表的索引

删除索引
drop index 索引名 on 表名;

drop index student_sname_index on student;

将student表上的student_sname_index索引对象删除。

explain 查询语句
explain 可以查看 SQL 执行计划,这里就可以查看一个SQL语句是否使用了索引进行检索:

explain select * from student where sloc = "北京";
explain select * from student where sname = '张三';
explain select * from student where sid = '10';

在这里插入图片描述

注意:在 mysql 当中,主键(PK)上,以及 unique 字段上都会自动添加索引的。

三、添加索引的条件

什么条件下,我们会考虑给字段添加索引呢?

  • 条件1: 数据量庞大(到底有多么庞大算庞大,这个需要测试,因为每一个硬件环境不同)
  • 条件2: 该字段经常出现在 where 的后面,以条件的形式存在,也就是说这个字段总是被扫描。
  • 条件3: 该字段很少的 DML(insert delete update) 操作。因为DML之后,索引需要重新排序,维护开销大。

使用索引注意事项:

  1. 建议不要随意添加索引,因为索引也是需要维护的,太多的话反而会降低系统的性能。
  2. 建议通过主键或通过 unique 约束的字段进行查询,效率是比较高的。
  3. 如果表里的数据很大,建立索引的开销也会很大。好的做法是创建表之初就把索引设定好。

四、索引失效的几种情况

提示:此时 SID 和 SNAME 均有索引

1、模糊匹配当中以“%”开头。

explain select * from student where sname like '%张';

2、不合理使用 or

使用 or 的时候会失效,如果使用 or ,那么要求 or 两边的条件字段都要有索引,才会走索引,如果其中一边有一个字段没有索引,那么另一个字段上的索引也会失效。所以不建议使用 or 建议 union。

explain select * from student where sname = '张三' or sloc = '北京';

3、在where当中索引列参加了运算,索引失效。

explain select * from student where sid+10 = 20;

4、在where当中索引列使用了函数。

explain select * from emp where upper(sname) = 'JACK';

五、索引背后的数据结构

1、概述

在实际中,汉语字典前面的目录是排序的,按照a b c d e f…排序,为什么排序呢?因为只有排序了才会有区间查找这一说!在mysql数据库当中索引也是需要排序的,因此索引底层需要维护一种用于排序查询的数据结构,我们知道二叉搜索树,平衡二叉树和哈希表均可用于查询,那么MySQL索引底层为什么不采用以上数据结构呢?正是因为它们都存在一定的缺陷:

  1. 二叉搜索树:二叉搜索树有良好的查找和插入性能,但是二叉查找树构建可能极不平衡,甚至会导致时间复杂度退化到O(n),就会极大增加IO次数,大大降低查找性能。
  2. 平衡二叉树:平衡二叉树解决了二叉搜索树可能高度不平衡的问题,比普通二叉搜索树更优秀的平均性能,但是随着数据规模增大,树的高度仍然会变得很高,IO次数就会增多,导致性能下降。
  3. 哈希表:哈希表虽然是O(1)时间复杂度查询,但是最大的问题在于只能进行key值相等的比较,如果想进行诸如大于小于的范围比较,或模糊匹配哈希表都是无能为力的。(不对索引进行排序)

因此为了解决以上缺陷,我们引入了B树又叫B-树(B杠树)和B+树。在MySQL中,索引的底层使用的是B+树的数据结构。又或叫做下面我们就简单了解一下B树和B+这两种数据结构。

2、B树

B树是一种多路搜索树,可以认为是一颗N叉搜索树,一个m 阶的B树指的是一个节点最多拥有 m 个孩子节点,而不是指的树的高度,即3阶 B-tree 是每个节点都最多拥有3个孩子节点。对于B树的定义比较复杂,咱们直接看图:

据上图,我们可以更清晰的观察到B树的特点:

  1. B树的每个结点可以存放N行记录,N行记录又可以根据key值划分出N+1个区间。即每个结点的每个记录的左子树存放比当前记录key值小的记录,右子树存放比当前记录大的记录。
  2. 由于B树的每个结点可以存放多个记录,那么同样的数据量的情况下,这种数据结构可以大大降低树的高度,减少了IO次数。

3、B+树

B+树是在B树的基础上做出了改进,其实也是一种多路搜索树。同样一图胜千言,我们直接看图:


从图中我们不难总结出B+树特点:

  1. 一个结点可以存储N个key,N个key可以划分出N个区间。
  2. 每个节点中的key值都会在子节点中存在,同时key是当前子节点的最大值。
  3. B+树的叶子结点之间都有指针相连,在MySQL中优化成了循环链表。
  4. 在MySQL中,由于叶子结点是完整的数据集合,因此只在叶子结点中存储数据表的每一行数据,而非叶子结点只存储key值(索引)本身。

B+树在B树的基础上进行了改进,MySQL索引底层就是维护了一个B+树的数据结构。对于B+树相比于其他用于查询的数据结构,其优势是明显的:

  1. 首先它是在B树的基础上进行的迭代,具有一个节点保存更多的key的特点,这就导致相同数据量的情况下,最终树的高度是相对更矮的,查询的时候减少了IO访问次数。
  2. 所有的查询最终都会落到叶子结点上,查询任何一个数据,经过的IO访问次数是一样的,也就是说B+树的IO访问次数更加稳定,这可以让程序员对于程序的执行效率有一个更准确的评估。
  3. B+树的所有叶子节点构成链表,此时会比较方便进行范围查询。 例如参照上图,假设key值为ID,查询ID>5 并且ID<11的同学,只需要先找到5所在的位置,再找到11所在的位置,之后在叶子结点中的5到11进行遍历,中间结果即为所求。
  4. 对于B树,由于每个结点中都存放完整的数据,因此占用空间较大,由于内存空间有限,因此不适合在内存缓存。而B+树,所有的数据都在叶子节点上,非叶子结点只存储key(索引),导致非叶子结点占用空间比较小,这些非叶子结点就可能在内存中缓存,或者缓存一部分,这样之后在进行查询时就不用读取硬盘了,又进一步减少了IO次数。

4、如果一个表中有多个索引(回表现象)

假设有一个学生表student(ID,Name,Score),其中ID为主键,此时我们创建Name索引,进行查询时MySQL内部会出现如下现象:

MySQL内部会先以ID为主键,构建出B+树,通过叶子结点组织所有行。其次针对Name这一列,会构建另外一个B+树,但是这个B+树的叶子结点就不再存储这一行的完整数据,而是存主键ID。此时如果你根据name来查询,查到叶子结点得到的只是主键ID,还需要再通过主键ID的B+树里再查询一次。这个过程被称为“回表”,是mysql自动完成的,用户感知不到。

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

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

相关文章

Unity实现安卓App预览图片、Pdf文件和视频的一种解决方案

一、问题背景 最近在开发app项目&#xff0c;其中有个需求就是需要在app软件内显示图片、pdf和视频&#xff0c;一开始想的解决方案是分开实现&#xff0c;也就是用Image组件显示图片&#xff0c;找一个加载pdf的插件和播放视频的插件&#xff0c;转念一想觉得太麻烦了&#x…

StarRocks下载使用说明和基础操作

简介 StarRocks 是一款高性能分析型数据仓库&#xff0c;使用向量化、MPP 架构、CBO、智能物化视图、可实时更新的列式存储引擎等技术实现多维、实时、高并发的数据分析。StarRocks 既支持从各类实时和离线的数据源高效导入数据&#xff0c;也支持直接分析数据湖上各种格式的数…

【productj服务导出文件503问题】

设备服务只要导出文件&#xff0c;就报503&#xff0c;查看K8S发现服务重启 1. 复现问题1.1 问题复现频繁fullGC 宿主pod服务日志监控1.2 小内存复现 接口没啥问题&#xff0c;导出就会导致服务重启 1. 复现问题 当前uat环境配置&#xff1a; pod内存&#xff1a;2G JVM参数&a…

力扣 第 134 场双周赛 解题报告 | 珂学家

前言 题解 T1/T3是环形的处理技巧&#xff0c;这边可以double数组(更准确地讲&#xff0c;添加一个合适的小尾巴). T4是典题&#xff0c;前不久周赛刚考过&#xff0c;是一道结论题&#xff0c;也可以借助数据结构处理。 T1. 交替组 I 和T3一起讲 T2. 与敌人战斗后的最大分数…

Docker-11☆ Docker Compose部署RuoYi-Cloud

一、环境准备 1.安装Docker 附:Docker-02-01☆ Docker在线下载安装与配置(linux) 2.安装Docker Compose 附:Docker-10☆ Docker Compose 二、源码下载 若依官网:RuoYi 若依官方网站 鼠标放到"源码地址"上,点击"RuoYi-Cloud 微服务版"。 跳转至G…

Qwen知识蒸馏小试牛刀,在MT-Bench与AlpacaEval 2.0的表现大幅提升

Qwen知识蒸馏小试牛刀&#xff0c;在MT-Bench与AlpacaEval 2.0的表现大幅提升 原创 荷风微摆 YeungNLP 2024年07月08日 01 前言 本文主要分享我们在大模型知识蒸馏上的实验尝试&#xff0c;以及所取得的实验效果提升。我们在5月份完成了该实验&#xff0c;但由于各种原因&…

Springboot实战:AI大模型+亮数据代理助力短视频时代

目录 前言1.如何入门亮数据1.1、注册登录1.2、注册账号1.3、登录1.4、购买静态住宅代理1.5、展示购买的代理 2. 使用Springboot、AI大模型构建系统2.1 使用Springboot、AI大模型构建爬虫2.2、在Springboot项目添加工具 3、编写代码&#xff0c;爬取视频素材3.1、代码里使用代理…

I 2U-Net:具有丰富信息交互的双路径 U-Net 用于医学图像分割| 文献速递-基于深度学习的多模态数据分析与生存分析

Title 题目 I 2U-Net: A dual-path U-Net with rich information interaction for medical image segmentation I 2U-Net&#xff1a;具有丰富信息交互的双路径 U-Net 用于医学图像分割 01 文献速递介绍 在计算机视觉领域&#xff0c;医学图像分割是一个主要挑战&#xff…

深入解析:抖音视频标题的Python爬虫提取方法

引言 随着短视频的兴起&#xff0c;抖音已经成为全球最受欢迎的社交媒体平台之一。对于数据分析师、市场研究人员以及内容创作者来说&#xff0c;能够从抖音上抓取数据是一项宝贵的技能。本文将深入解析如何使用Python编写爬虫程序来提取抖音视频的标题。 爬虫基础 在开始编…

家里猫咪浮毛太多怎么办?值得买的猫毛空气净化器推荐

作为一位拥有5年铲屎经验的铲屎官&#xff0c;我知道许多新手铲屎官可能听说过宠物空气净化器&#xff0c;但了解得不多。事实上&#xff0c;宠物空气净化器确实是养猫家庭必备的小家电之一。它的大面积进风口可以有效吸附空气中的微小浮毛和皮屑&#xff0c;专门的除臭技术能有…

使用 Python 处理 Lumerical 导出的 .txt 文件(完结)

使用 Python 处理 Lumerical 导出的 .txt 文件 引言正文以 , 隔开的波长与透射率以 \t 隔开的波长与透射率引言 之前在 添加链接描述 一文中我们已经介绍了如何将 Lumerical 仿真中的 S 参数相关数据导出为 .txt 文件。这里我们来分享如何使用 Python 对这些数据进行处理。 正…

旋转木马案例

旋转木马 如果接口需要的数据格式和原始数据提供的格式有差异 不要去改接口方法 也不要改原始数据 做一层中间件(数据处理函数/方法) <!DOCTYPE html> <html lang"zh-cn"><head><meta charset"UTF-8"><meta name"viewport…

分销密文下单

背景 事情的经过就是今天早上一共下了10个单&#xff0c;然后就下不了单了。 如下图&#xff1a; 来到抖店后台显示什么解密额度已经用完了 所以&#xff0c;今天必须把困扰我很久的分销密文下单解决掉 操作 1688分销下单-逸淘订单 1 先关联商品 2 下单 首页导航栏--1688分…

重塑通信边界,基于ZYNQ7000 FPGA驱动的多频段多协议软件无线电平台

01、产品概述 本平台是基于高性能ZYNQ-7000系列中的XC7Z045处理器构建的多频段多协议软件无线电解决方案&#xff0c;集成了AD9364芯片——一款业界领先的1x1通道RF敏捷收发器&#xff0c;为无线通信应用提供了强大支持。其存储架构包括2路高速4GB DDR3内存、1路32GB EMMC存储以…

可信验证解释

学习目标&#xff1a;可信验证解释 可信验证是一种基于计算机技术和安全机制&#xff0c;用于确保系统、程序或数据的完整性和可信性的方法。以下是关于可信验证的详细解释&#xff1a;一、定义与原理 可信验证指的是利用计算机技术和安全机制&#xff0c;对系统、程序或数据…

MobaXterm工具

MobaXterm 是一个增强型的 Windows 终端。其为 Windows 桌面提供所有重要的远程网络终端工具&#xff08;如 SSH、X11、RDP、VNC、FTP、SFTP、Telnet、Serial、Mosh、WSL 等&#xff09;&#xff0c;和 Unix 命令&#xff08;如 bash、ls、cat、sed、grep、awk、rsync 等&#…

深度学习编码解码结构-以及kreas简单实现

图像分割中的编码解码结构&#xff08;Encoder-Decoder Model&#xff09;是一种广泛应用的网络架构&#xff0c;它有效地结合了特征提取&#xff08;编码&#xff09;和分割结果生成&#xff08;解码&#xff09;两个过程。以下是对图像分割中编码解码结构的详细解析&#xff…

写一个函数,返回参数二进制中 1 的个数

代码要求 输入一个整数n&#xff0c;输出该数32位二进制中为1的个数&#xff08;包括最高位的符号位&#xff09;&#xff0c;其中负数用补码表示 如&#xff1a;输入&#xff1a;15 &#xff08;15的二进制表示&#xff1a;0000 1111&#xff09; 输出&#xff1a;4 代码实…

音频demo:使用fdk-aac将PCM数据编码成aac数据

1、README a. 编译 编译demo 本demo是使用的开源项目fdk-aac将PCM数据编码成aac音频文件。由于提供的.a静态库是在x86_64的机器上编译的&#xff0c;所以默认情况下仅支持该架构的主机上编译运行。 $ make编译fdk-aac&#xff08;可选&#xff09; 如果想要在其他架构的CP…