MySQL - 4种基本索引、聚簇索引和非聚索引、索引失效情况

目录

一、索引

1.1、简单介绍

1.2、索引的分类

1.2.1、主键索引

1.2.2、单值索引(单列索引、普通索引)

1.2.3、唯一索引

1.2.4、复合索引

1.2.5、复合索引经典问题

1.3、索引原理

1.3.1、主键自动排序

1.3.2、索引的底层原理

1.3.3、B 树和 B+树的区别

1.4、聚簇索引和非聚簇索引

1.4.1、innoDB 中的主键索引

1.4.2、使用聚簇索引的优势

1.4.3、使用聚簇索引需要注意什么

1.4.4、为什么主键通常建议使用自增 id

1.5、索引失效的场景


一、索引


1.1、简单介绍

索引就是一种帮助  mysql 提高查询效率的数据结构.

优点:

  1. 大大增加了查询速度.

缺点:

  1. 索引实际上是一张表,因此需要消耗一部分空间资源.
  2. 对表中的数据进行增删改的时候,需要更新索引,因此速度会受到一定影响.

1.2、索引的分类

1.2.1、主键索引

实际上就是我们创建数据库时指定的主键(主键索引值不能为空、不能重复.),会自动创建索引,叫做 “主键索引”,在 innodb 引擎中就是所谓的 “聚簇索引”.

例如,以 id 为主键建表

create table user(id int PRIMARY KEY, name varchar(20), age int);

然后通过以下命令查看 user 表的索引

show index from user;

 

1.2.2、单值索引(单列索引、普通索引)

就是为表中的某一列创建的索引,一个表中可以有多个单列索引. 

例如,表中有字段 id、name、age,那么为 其中的 name 创建一个索引,就叫单列索引.

创建方式有以下两种:

a)建表时创建(注意,这种方式创建,索引名和字段名一致)

# 给 name 单独创建索引
create table user(id int primary key, name varchar(20), age int, key(name));# 给 name 和 age 分别创建索引
create table user(id int primary key, name varchar(20), age int, key(name), key(age));

b)建表后创建

create table user(id int primary key, name varchar(20), age int);create index index_name on user(name);

c)删除索引

drop index 索引名 on 表明

 

1.2.3、唯一索引

在创建表的时候,有时候我们会通过 unique 指定某个字段唯一,这个时候就会创建唯一索引.

Ps:允许有 null 值,并且可以有多个.

创建方式有以下两种:

a)建表时指定

# 第一种写法
create table user(id int primary key, name varchar(20) unique, age int);# 第二种写法
create table user(id int primary key, name varchar(20), age int, unique(name));

b)建表后创建

create unique index index_name on user(name);

1.2.4、复合索引

就是我们为表中的多个字段一起创建一个索引. 

Ps:查询时,在 where 条件后,必须要使用 and 连接复合索引字段,否则不生效.

创建方式有以下两种:

a)建表时创建

create table user(id int primary key, name varchar(20), age int, key(name, age));

b)建表后创建

create index name_age_index on user(name, age);

1.2.5、复合索引经典问题

问题:有一个用户表,给 name、age、gender 三个字段创建了一个复合索引 key(name, age, gender),以下场景,哪种查询索引会生效?

以下是 where 查询后通过 and 拼接的字段.

  1. name                          生效
  2. name  age                  生效
  3. name  age  gender     生效
  4. name  gender  age     生效
  5. age  gender                失效
  6. gender                        失效
  7. gender  age  name     生效

该怎么判断呢?符合索引生效只要满足以下任意一个原则即可:

  1. 最左前缀元组:必须包含做前缀,也就意味着 name、 name age、name age gender 是生效的.
  2. mysql 引擎为了更好的利用索引,在查询过程中会动态调整查询字段顺序,便于利用索引,也就意味着只要包含所有索引字段即可(任意的组合都可以).

1.3、索引原理

1.3.1、主键自动排序

当我创建一个 user 表(含主键 id),然后按照无序 id 的方式插入数据,会发现查询结果尽然按照 主键 id 排序了

为什么会进行排序呢?

排序之后相对来说,查询更快.  例如有 10 个自增 id,现在查询 id = 3 的,那么只需要向下对比三次即可得到,而对于无序数据来说每次都需要遍历一遍数据才能得到.

这也就说明为啥主键不建议使用 uuid 去建立,而是使用 int 类型?因为在主键建立索引的时候,会先根据表中的主键去排序,排序后在查询效率会更高.

1.3.2、索引的底层原理

假设有如下表和信息

索引的数据结构就是一个 b+ 树,原理如下

a)排序,形成链表:表中的每一条数据组织成一个链表中的一个节点,结构由三部分构成:“主键 + 数据 + 指针”,数据就是表中的非主键索引字段(name, age),指针就是用来指向下一个节点,这些节点会现经过主键 id 的排序,最后组织成一个链表的结构,得到b+树的叶子节点 如下

b)页管理:将链表进行分页管理,每一页的大小默认存储 16kb,假设如下图(真实情况一页存放的数据有很多).

c)页目录管理:将每一页最左边节点的主键 和 指针 拿出来存放到页目录中,页目录的默认大小也是 16kb

d)如果页目录的大小占满了,那么可能还会继续向上生成页目录(父节点),不过一般开发存储的数据,树的高度都不会超过 4 的,也就是说,当需要查找某一数据时,最多只需要 1~3 次 I/O  操作(注意:顶层的根节点时在内存中的).

1.3.3、B 树和 B+树的区别

B+ 树相当于是在 B 上的一种优化,主要区别如下:

  1. B+ 树非叶子节点只存储键值对信息,B 树 data 数据也需要存储,而每一页的存储空间是有限的(默认 16 kb),那么如果 data 数据较大时,每个节点能存储的 key 就很少,进而导致树的深度较大,增大了查询时的磁盘 IO 次数(每一层都进行一次 IO).
  2. B+ 树的叶子节点保存全集数据,是一个链表结构,而非叶子节点只存储 key,大大增加了非叶子节点存储 key 的数量,降低了树高.

1.4、聚簇索引和非聚簇索引

1.4.1、innoDB 中的主键索引

聚簇索引:由 主键索引 和 辅助索引 构成.

主键索引:主键索引中,叶子节点保存表中每一行的所有数据,当需要查找例如 where Id = 14,就会去主键索引 B+ 树上找到的叶子节点,然后获取行数据.

Ps:如果没有定义主键,就会选择唯一且非空的索引代替,如果非空索引也没有,就会自己隐式定义一个主键作为聚簇索引

辅助索引(innoDB 中的非聚簇索引就是辅助索引):就是在聚簇索引之上建立的索引,一般来说就是表中给其他字段建立的索引(非主键索引),也就是 复合索引、单列索引、唯一索引,并且的叶子节点存储的不再是行物理地址,而是主键值,因此辅助索引最少需要二次查询才能找到数据,例如 where name='cyk',步骤如下

  1. 在辅助索引 B+ 树种检索 name,然后到达叶子节点获取对应的主键.
  2. 根据主键在聚簇索引 B+ 树种在及进行一次检索操作,最终到达叶子节点获取整行数据.

非聚簇索引:在 myisam 使用的是非聚簇索引,也由两颗 B+ 树构成(主键索引、辅助索引),主键索引B+树节点存储了主键,辅助索引 B+ 树种存储了辅助键.  叶子节点都是用一个地址指向真正的表的数据,因此辅助键无需像 innoDB 一样访问主键索引树.

1.4.2、使用聚簇索引的优势

问题:每次使用辅助索引检索都需要经过两次 B+ 树查询,看上去聚簇索引的效率明显低于非聚簇索引,这不是多此一举么,聚簇索引优势在哪?

  1. 访问同一数据也不同记录时,会把页加载到缓存中,再次访问的时候,会在内存中完成访问,不必访问磁盘,而主键和数据又是一起被载入内存的,因此按照主键 id 来组织数据(排好序的),获取更快.
  2. innoDB 中的辅助索引叶子节点存储主键值,而不是物理地址,因此当行数据发生改变时(对表进行增删改),叶子节点也无需像 myisam 非聚簇索引的辅助索引一样改变地址,只需要维护索引树即可.
  3. innoDB 中的辅助索引叶子节点存放的是主键值,而 myisam 中存储的是物理地址,因此空间占用更小.

1.4.3、使用聚簇索引需要注意什么

主键最好不要使用 uuid,因为 uuid 值过于离散,不适合排序,并且有可能生成的 uuid 插入在索引树的中间位置,导致树调整复杂度变大,查询时消耗更多的时间.

建议使用 int 或者 bigint 类型的自增,方便排序并且默认会在索引树的末尾增加主键值,对索引树的结构影响最小.

1.4.4、为什么主键通常建议使用自增 id

聚簇索引的数据物理地址存放顺序和索引主键 id 顺序时一致的,因此索引是相邻的,对应的数据也是在相邻的磁盘上. 如果主键不是自增 id,那么会不断调整数据的物理地址,来进行分页. 如果是自增,就只要一页一页写,磁盘碎片也就少了.

1.5、索引失效的场景

1. 查询语句中使用 like 关键字,如果匹配字符串的第一个字符为 "%",索引不会被使用;如果 "%" 不是在第一个位置,索引就会被使用.

2. 查询语句中使用复合索引,需要满足匹配原则才可以(上面讲到过了)。

3. 查询语句中使用 or 关键字时,如果 or 前后的两个条件都是索引,那么就会使用索引,如果任意一个不是索引,那么查询中不使用索引.  

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

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

相关文章

创作4周年

🙌秋名山码民的主页 😂oi退役选手,Java、大数据、单片机、IoT均有所涉猎,热爱技术,技术无罪 🎉欢迎关注🔎点赞👍收藏⭐️留言📝 获取源码,添加WX 目录 前言机…

哈希表-set、map

当需要判断一个元素是否在集合中时,就使用哈希法 散列表(Hash table,也叫哈希表),是根据键(Key)而直接访问在内存存储位置的数据结构。 哈希表中关键码就是数组的索引下标,然后通过…

app小程序开发的重点在哪里?|企业软件定制网站建设

app小程序开发的重点在哪里?|企业软件定制网站建设 App小程序定制开发是近年来快速发展的一项技术服务,随着移动互联网的普及和用户需求的不断升级,越来越多的企业和个人开始关注和需求定制化的小程序开发。那么,对于app小程序定制…

Springboot_文件下载功能(前端后端)

遇到的问题: 文件下载后文件一直被破坏,无法正常打开文件名乱码,如图 刚开始一直在纠结,是不是后端没有写对,然后导致下载不能使用 后来搜索了一些资料,发现后端没什么问题 然后就开始找到其他项目对比…

头发的方向图(2D和3D)与合成

首先,我们从一个不受光照限制的环境中拍摄一组输入图像,这些图像包含了头发的不同视角和姿态。我们对这些图像进行半自动的分割,将头发从背景中分离出来,然后使用PMVS ,一种先进的多视角立体算法,来重建一个…

广播组播、本地套接字通信、wireshark、以太网帧格式、三次握手四次挥手

广播(使用 UDP 套接字) 广播地址:主机号最大的地址。 广播:给所在局域网的所有主机发送数据报。(之前的数据报发送方式是单播。) 以下情况中使用广播: 局域网 搜索协议。 比如家中的智能产品&a…

局域网共享打印机共享,简单至简至一键处理011bDll等问题

一、电脑系统是否激活(可选) 二、确保主客户端PC在同一局域网内(可选) 可以通过ping 目标地址 如ping 192.168.1.202;看是否可以正常通信 下面是惠普类型打印机共享问题关键(文本记得保存) …

双11再创新高!家电行业如何通过矩阵管理,赋能品牌增长?

双11大促已落下帷幕,虽然今年不再战报满天飞,但从公布的数据来看,家电行业整体表现不俗。 根据抖音电商品牌业务发布的收官战报,家电行业创造了成交新纪录,整体同比增长125%。快手官方数据显示,消电家居行业…

深入理解JMM以及并发三大特性(1)

文章目录 1. 并发与并行2. JMM3. 并发三大特性4.总结 1. 并发与并行 并行:指在同一时刻,有多条指令在多个处理器上同时执行。所以无论从微观还是宏观来看,二者都是一起执行的。 并发:指在同一时刻只能有一个指令执行,…

基于springboot实现校园在线拍卖系统项目【项目源码】

基于springboot实现校园在线拍卖系统演示 Javar技术 JavaScript是一种网络脚本语言,广泛运用于web应用开发,可以用来添加网页的格式动态效果,该语言不用进行预编译就直接运行,可以直接嵌入HTML语言中,写成js语言&…

Modbus转Profinet改变局面,PLC与电力仪表秒级响应

Modbus转Profinet改变了传统的局面,实现了PLC与电力仪表之间的秒级响应。在过去,由于Modbus通信协议的限制,PLC与电力仪表之间的数据传输速度受到了很大的限制,无法满足工业自动化领域对实时性的要求。然而,随着Modbus…

【云原生 Prometheus篇】Prometheus架构详解与核心组件的应用实例(Exporters、Grafana...)

Prometheus Part1 一、常用的监控系统1.1 简介1.2 Prometheus和zabbix的区别 二、Prometheus2.1 简介2.2 Prometheus的主要组件1)Prometheus server2)Exporters3)Alertmanager4)Pushgateway5)Grafana 2.3 Prometheus的…

openGauss学习笔记-130 openGauss 数据库管理-参数设置-重设参数

文章目录 openGauss学习笔记-130 openGauss 数据库管理-参数设置-重设参数130.1 背景信息130.2 GUC参数设置130.3 操作步骤130.4 示例 openGauss学习笔记-130 openGauss 数据库管理-参数设置-重设参数 130.1 背景信息 openGauss提供了多种修改GUC参数的方法,用户可…

【网络】数据链路层协议

数据链路层协议 一、链路层解决的问题二、以太网协议1、局域网技术2、令牌环网(了解)3、以太网通信原理4、 MAC地址5、以太网帧格式6、碰撞避免7、最大传输单元MTU 二、ARP协议1、ARP数据的格式2、ARP协议的工作流程3、ARP缓存表4、ARP协议中的一些问题7…

11月23日星期四今日早报简报微语报早读

11月23日星期四,农历十月十一,早报微语早读。 1、我国5G基站总数达321.5万个; 2、2023年两院院士增选结果揭晓,共133人当选; 3、北京低保标准提升至每人每月1395元; 4、上海制定体育发展条例&#xff1a…

[Linux] shell脚本之循环

一、循环定义 一组被重复执行的语句称之为 循环体,能否继续重复,决定循环的终止条件。 循环语句 是由循环体及循环的终止条件两部分组成的。 二、for循环 2.1 带列表循环 语法 for 变量名 in 取值列表do 命令序列 done 花括号用法: 花括号{ }和seq在for循环…

年轻有为!2023两院院士增选揭榜 45岁颜宁当选

大家好,我是极智视界,欢迎关注我的公众号,获取我的更多前沿科技分享 邀您加入我的知识星球「极智视界」,星球内有超多好玩的项目实战源码和资源下载,链接:https://t.zsxq.com/0aiNxERDq 通常,两…

BTS-GAN:基于MRI和条件对抗性网络的乳腺肿瘤计算机辅助分割系统

BTS-GAN: Computer-aided segmentation system for breast tumor using MRI and conditional adversarial networks BTS-GAN:基于MRI和条件对抗性网络的乳腺肿瘤计算机辅助分割系统背景贡献实验方法Parallel dilated convolution module(并行扩展卷积模块…

逸学java【初级菜鸟篇】9.5枚举

hi,我是逸尘,一起学java吧 枚举是信息的标志和分类 当一个变量有几种固定可能的取值时,就可以将它定义为类型的枚举。 优点:代码可读性好,入参约束严谨,代码优雅,是最好的信息分类技术&#x…

【AI读论文】AutoML的8年回顾:分类、综述与趋势

论文标题:Eight years of AutoML: categorisation, review and trends 论文链接:https://link.springer.com/article/10.1007/s10115-023-01935-1 本文主要围绕自动机器学习(AutoML)展开了系统性的文献综述,总结了该领…