【MySQL | 第三篇】MySQL索引及两种索引分类方法总结

文章目录

  • 3.MySQL索引及两种索引分类方法
    • 3.1索引的概念
      • 3.1.1相关定义
      • 3.1.2查询例子
    • 3.2索引的底层
      • 3.2.1二叉树
        • (1)满二叉树
        • (2)完全二叉树
        • (3)二叉查找树
        • (4)二叉平衡树(AVL)
          • ①区分深度和高度
          • ②平衡因子
          • ③特点
        • (5)红黑树(BST)
      • 3.2.2B树
      • 3.2.3B+树
    • 3.3索引的类型
      • 3.3.1按功能逻辑区分
        • (1)主键索引——Primary key(column)
        • (2)唯一索引——Unique(column)
        • (3)普通索引——Index index_name(column)
        • (4)全文索引——Fulltext(column)
        • (5)前缀索引——Key(column_name(prefix_length))
        • (6)组合索引——Index index_name(column1,column2)
        • (7)空间索引
      • 3.3.2按底层数据结构区分
        • (1)聚簇索引&&非聚簇索引(二级索引)
      • 3.3.3InnDB存储引擎的两种索引
        • (1)InnoDB——主键索引(聚簇索引)
        • (2)InnDO——辅助索引(非聚簇索引(二级索引))
        • (3)主键搜索过程
      • 3.3.4MyISAM的索引
        • (1)MyISAM——主键索引(非聚簇索引)
        • (2)MyISAM-辅助索引(非聚簇索引)
    • 3.4相关概念(回表/索引覆盖/索引下推)
      • 3.4.1回表
      • 3.4.2索引覆盖
      • 3.4.3索引下推
    • 3.5参考文章链接
    • 3.6总结

在这里插入图片描述

3.MySQL索引及两种索引分类方法

3.1索引的概念

3.1.1相关定义

  1. 索引(在MySQL中也叫做“键(key)”)是存储引擎用于快速找到记录的一种数据结构,这也是索引最基本的功能。
  2. 索引优化是查询性能优化最有效的手段。
  3. 如果想要在一本书中找到某个特定主题,一般会先看书的目录,找到对应的页码,然后直接翻到对应的页码即可查看。在MySQL中,存储引擎用类似的方法使用索引,首先在索引中找到对应的值,然后根据匹配的索引记录找到对应的数据行。简单的说,数据库索引类似于书前面的目录,能加快数据库的查询速度。

3.1.2查询例子

select name from user where user_id = 5 
  1. 如果user_id列上建有索引,则MySQL将使用该索引找到user_id 为 5的行,即MySQL现在索引上按值进行查找,然后返回包含该值的数据行。
  2. 索引可以一个或多个列的值,如果索引包含多个列,那么列的顺序也很重要,因为MySQL只能高效地使用最左前缀列。

3.2索引的底层

  1. MySQL默认使用的索引的底层数据结构是 B+树
  2. 以下将介绍二叉树、满二叉树、完全二叉树、二叉查找树、二叉平衡树(AVL)、红黑树(BST)
  3. B树、B+树

3.2.1二叉树

  • 特点:每个节点最多有两个子树的树结构
(1)满二叉树
  • 特点:除了叶子节点外,每一个节点都有两个子节点,且所有叶子节点都在二叉树的同一高度上
(2)完全二叉树
  • 特点:完全二叉树 除去底层节点后为满二叉树,且底层节点依次从左到右分布
(3)二叉查找树
  • 特点:任意一个节点的值大于左子树任意一个节点的值,小于右子树任意一个节点的值
(4)二叉平衡树(AVL)
①区分深度和高度
  • 深度

    • 根节点深度为0
    • 从根节点自顶向下逐层累加
  • 高度

    • 叶子节点高度为0
    • 从叶子节点自底向上逐层累加
②平衡因子
  • 平衡因子:该节点的左子树深度-右子树深度
③特点

特点:树中任一节点的两个子树的平衡因子的绝对值不超过1(重要)

(5)红黑树(BST)
  • 红黑树是一棵自平衡搜索树

  • 规则

    • 根节点总是黑色
    • 每个节点只能是红色或黑色
    • 红色节点的父或子节点必然是黑色的(即两个红色的节点不会相连)
    • 任意节点到后代NULL节点的每条路径都具有相同数量的黑色节点
    • 每个NULL节点都是黑色的
  • 如何保证平衡

    • 左旋/右旋
      • 左旋:根节点往左偏转,将右子树的第一个节点变成根节点
      • 右旋:根节点往右偏转,将左子树的第一个节点变成根节点
    • 染色:更改根子节点的颜色,确保满足规则

3.2.2B树

  1. B树即一棵多(m)路平衡查找树
    1. 字母m表示阶数,一个结点最多有多少个孩子结点,同时m必须>2
    2. 一个结点中同时存储关键字、以及指向儿子节点的指针
  2. 特点:
    1. 关键字数据分布在整棵树中,即数据均分布在树中
    2. 任何一个关键字仅且出现在一个节点

3.2.3B+树

  1. 基于B树进行改造的树,更适合海量数据的存储
  2. 特点
    1. 所有关键字均分布在叶子节点的链表
    2. 非叶子节点不存储关键字,只存储key以及指向儿子节点的指针
    3. 叶子节点之间互相串联,首尾相连
  3. 与B树对比:
    1. 磁盘读写代价更低
    2. 查询效率更稳定
    3. 更便于扫库和区间扫描

3.3索引的类型

3.3.1按功能逻辑区分

(1)主键索引——Primary key(column)
  • 定义:数据列不允许重复不允许为NULL,一个表只能有一个主键

  • 举例:

    ALTER TABLE table_name ADD PRIMARY KEY (column);
    
(2)唯一索引——Unique(column)
  • 定义:索引列中的值必须是唯一的,但是允许NULL值。建立唯一索引的目的大部分时候都是为了该属性列的数据的唯一性,而不是为了查询效率。一个表允许多个列创建唯一索引。

  • 举例:

    ALTER TABLE table_name ADD UNIQUE (column);
    
(3)普通索引——Index index_name(column)
  • 定义:MySQL中基本索引类型,没有什么限制,允许在定义索引的列中插入重复值和NULL值。一个表允许多个列创建普通索引

  • 举例:

    ALTER TABLE table_name ADD INDEX index_name (column);
    
(4)全文索引——Fulltext(column)
  • 定义:主要是为了快速检索大文本数据中的关键字的信息。字段长度比较大时,如果创建普通索引,在进行like模糊查询时效率比较低,这时可以创建全文索引,基于倒排索引,类似于搜索引擎。MyISAM存储引擎支持全文索引,InnoDB 存储引擎在 MySQL 5.6.4 版本中也开始支持全文索引

  • 举例:

    ALTER TABLE table_name ADD FULLTEXT (column);
    
(5)前缀索引——Key(column_name(prefix_length))
  • 定义:在文本类型如BLOB、TEXT或者很长的VARCHAR列上创建索引时,可以使用前缀索引,数据量相比普通索引更小,可以指定索引列的长度,但是数值类型不能指定

  • 举例:

    ALTER TABLE table_name ADD KEY(column_name(prefix_length));
    
(6)组合索引——Index index_name(column1,column2)
  • 定义:指多个字段上创建的索引,只有在查询条件中使用了创建索引时的第一个字段,索引才会被使用。使用组合索引时遵循最左前缀原则。

  • 主键索引、普通索引、唯一索引等都可以使用多个字段形成组合索引

  • 举例:

    ALTER TABLE table_name ADD INDEX index_name ( column1, column2, column3 )
    
(7)空间索引
  • 定义:MySQL在5.7之后的版本支持了空间索引,而且支持OpenGIS几何数据模型。MySQL在空间索引这方面遵循OpenGIS几何数据模型规则。

3.3.2按底层数据结构区分

在前面已经介绍过了MySQL索引默认的底层数据结构为B+树,还要以下相关索引的特点

  • 它是一棵 B+Tree
  • 每一个 B+Tree 的节点都是一个「数据页」
  • 索引是在存储引擎层实现的,所以并没有统一的索引标准,即不同存储引擎的索引的工作方式并不一样
(1)聚簇索引&&非聚簇索引(二级索引)
  • 聚簇索引:
    • 数据存储与索引放到了一块,索引结构的叶子节点保存了行数据(所有字段的值)
    • 有且仅有一个
    • 规则
      • 依次选择主键索引、唯一索引作为聚簇索引
      • InnoDB自动生成一个rowid作为隐藏的聚簇索引
  • 非聚簇索引:
    • 数据与索引分开存储,索引结构的叶子节点指向了数据对应的位置
    • 可以存在多个

3.3.3InnDB存储引擎的两种索引

在InnoDB存储引擎中,主键索引和辅助索引的索引类型分别为聚簇索引和非聚簇索引

(1)InnoDB——主键索引(聚簇索引)

img

(2)InnDO——辅助索引(非聚簇索引(二级索引))

img

(3)主键搜索过程

在这里插入图片描述

整个查询的过程如下

  1. 查询 id(主键) 为 18 的数据,SELECT id, name, age WHERE id = 18。
  2. 首先在「根节点:节点一」上,id = 18 落在了 15 <= id < 56 范围之内,这样我们就知道了下级节点「非叶子节点:节点2-1」的地址。
  3. 根据【步骤2】得到的「非叶子节点:节点2-1」的地址,找到对应的「非叶子节点:节点2-1」。然后,id = 18 又落在了 15 <= id < 20 范围之内,这样我们就知道了再下一级节点「叶子节点:节点3-1」的地址。
  4. 根据【步骤3】得到的「叶子节点:节点3-1」的地址,找到对应的「叶子节点:节点3-1」。最后,在「叶子节点:节点3-1」这个节点上找到 id = 18 对应的数据 {“id”: 18, “name”: “King”, “age”: 17}

3.3.4MyISAM的索引

  1. 在存储引擎为 MyISAM 的表中,主键索引和辅助索引的类型都是非聚簇索引
  2. 两棵 B+Tree 的结构完全一致,只是存储的内容不同
    1. 主键索引 B+Tree 的节点存储了 「主键」+「数据记录的地址」
    2. 辅助键索引 B+Tree 存储了 「索引列的值」+「数据记录的地址」
  3. 还有一点不同是主键索引中的 key 必须是唯一的,而辅助索引中的 key 可以重复
(1)MyISAM——主键索引(非聚簇索引)

在这里插入图片描述

(2)MyISAM-辅助索引(非聚簇索引)

在这里插入图片描述

3.4相关概念(回表/索引覆盖/索引下推)

3.4.1回表

  • 定义:通过二级索引找到对应的主键值,再到聚簇索引中查找整行数据的过程

主要发生在通过辅助索引查询的时候,通过辅助索引找到 B+Tree 中的叶子结点,但是辅助索引的叶子节点内存储的数据不全,只有索引列的值和主键值。我们还需要拿着刚从辅助索引中得到的主键值再去聚簇索引(主键索引)的叶子节点中去拿到完整的数据(全部字段),这个过程就叫「回表」

3.4.2索引覆盖

  • 定义:指第一次使用了索引,并且找到了全部所有需要返回的数据

  • 例子:

    • 使用id查询,直接使用聚簇索引,返回数据
    • 如果返回的列,在索引存储的数据没有找到,就会触发回表查询
  • 结论:避免使用select *

  • 应用:解决MySQL超大分页

    • 原:

      select * from tb_sku limit 900000,10
      
    • 改:通过子查询+覆盖索引解决:在子查询中,先通过按 id 排序选择第 9000000 到第 9000009 行的数据,并拿到id,再通过id,由覆盖索引查到详细数据

      select * 
      from tb_sku t,(select id from tb_sku order by id limit 9000000,10) a 
      where t.id=a
      

3.4.3索引下推

索引下推,严格来说应该叫「索引条件下推」。该功能是 MySQL 数据库 5.6 版本添加的,用于优化数据查询,默认情况处于开启状态。我们可以通过如下命令来开启和关闭「索引条件下推」功能:

  • 开启
SET optimizer_switch = 'index_condition_pushdown=on'
  • 关闭
SET optimizer_switch = 'index_condition_pushdown=off'

下面通过一个例子来说下什么是「索引条件下推」,首先我们假设有这么一张表:

  • 表名:t_user
  • 字段:id,name,mobile
  • 辅助索引:name + mobile(索引名:name_mobile_normal)

表结构如下:

CREATE TABLE `t_user` (`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '编号',`name` varchar(100) COLLATE utf8_bin NOT NULL COMMENT '姓名',`mobile` varchar(200) COLLATE utf8_bin NOT NULL COMMENT '手机',PRIMARY KEY (`id`) USING BTREE,KEY `name_mobile_normal` (`name`,`mobile`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='用户表';

下面,让我们来分别看下关闭和开启「索引条件下推」这两种情况,下边这个查询语句的执行计划有怎样的不同。

EXPLAIN SELECT * FROM t_user WHERE name = 'A' AND mobile LIKE '%138'
  • 关闭「索引条件下推」
    在这里插入图片描述

  • 开启「索引条件下推」
    在这里插入图片描述

  • 从上边,我们可以看到,关闭「索引条件下推」时候 Extra 是 Using where;开启「索引条件下推」时候 Extra 是 Using index condition。

当关闭「索引条件下推」的时候,MySQL 首先通过索引将匹配 name = ‘A’ 的数据都查出来(在存储引擎中完成),然后再从这些数据中找到与 mobile LIKE ‘%138’ 条件相匹配的数据(在 Server 层完成)。

当开启「索引条件下推」的时候,因为 name 和 mobile 对应的值已经都存储在索引中了(也就是说我们可以直接拿到这个值,来判断数据是否与查询条件匹配),这样就可以直接在存储引擎中完成数据的查询了。

综上所述,索引条件下推就是 “过滤的动作 尽量由 下层的存储引擎层 通过 使用索引 来完成,而不需要上推到 Server 层进行处理” ,实现的主要思路是充分利用索引中存储的数据,尽量把根据条件过滤数据的操作交给存储引擎来做(这样可以最大限度的减少需要「回表」的数据)。

最后,还需要注意的是由于该技术基于存储引擎,只有特定的存储引擎可以使用。而且,条件判断操作必须可以在存储引擎运行,比如调用存储过程的条件就不可以,因为存储引擎没有调用存储过程的能力。

3.5参考文章链接

  1. MySQL中的 索引、聚簇索引、非聚簇索引、回表、索引覆盖、索引下推 都是啥?

3.6总结

MySQL系列第三篇主要介绍了MySQL索引的定义,深入理解索引的底层数据结果(B+树),还介绍了其他树的特点,最后按功能逻辑和按底层数据结构两种分类方法将索引分别分类,其中重点为聚簇索引和非聚簇索引,我们需要理解并记住两种索引的区别,最后最后介绍了InnoDB和MyiSAM两种引擎下,主键索引和辅助索引对应聚簇索引还是非聚簇索引,还介绍了回表查询、覆盖索引、以及索引下推等相关概念

在这里插入图片描述

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

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

相关文章

HTML静态网页成品作业(HTML+CSS)——电影网首页网页设计制作(1个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有1个页面。 二、作品演示 三、代…

Vue3_2024_6天【回顾上篇watch常见的前三种场景】另两种待补

第一种情况&#xff1a;监视【ref】定义&#xff08;基本数据类型&#xff09; 1.引入watch2.格式&#xff1a;watch&#xff08;基本数据类型数据&#xff0c;监视变化的回调函数&#xff09; 注意点&#xff1a; 2.1.watch里面第一个参数&#xff0c;是数据~~【监视的基本类…

[Buuctf] [MRCTF2020] Xor

运行 1.查壳 32位exe文件&#xff0c;没有壳 2.用32位IDA打开 找到main函数&#xff0c;F5查看伪代码&#xff0c;但是这里会弹出一个窗口 函数分析失败&#xff01;&#xff01; 这里我在看别人的题解时发现一种玄学方式解决了这个问题 窗口里面弹出了一个地址401095&…

LVS+Keepalived 高可用负载均衡集群

一. 高可用集群的相关知识 1.1 高可用&#xff08;HA&#xff09;集群和普通集群的比较 ① 普通集群 普通的群集的部署是通过一台度器控制调配多台节点服务器进行业务请求的处理&#xff0c;但是仅仅是一台调度器&#xff0c;就会存在极大的单点故障风险&#xff0c;当该调度…

蓝桥杯备赛之二分专题

常用的算法二分模板 1. 在数组a[]中找大于等于x的第一个数的下标 //int ans lower_bound(a, a n, x) - a //相当于下方 int l 0, r n - 1; while(l < r) {int mid l r >> 1;if(a[mid] > x) r mid;else l mid 1; } cout << r;2. 在数组a[]中找大于…

qml中toolbox控件、ComboBox控件、PlainText实现及美化

一. 内容简介 qml中toolbox控件、ComboBox控件、PlainText实现及美化 二. 软件环境 2.1vsCode 2.2Anaconda version: conda 22.9.0 2.3pytorch 安装pytorch(http://t.csdnimg.cn/GVP23) 2.4QT 5.14.1 新版QT6.4,&#xff0c;6.5在线安装经常失败&#xff0c;而5.9版本…

亚马逊运营要使用什么海外代理IP?

代理IP作为网络活动的有力工具&#xff0c;同时也是跨境电商的必备神器。亚马逊作为跨境电商的头部平台&#xff0c;吸引了大量的跨境电商玩家入驻&#xff0c;想要做好亚马逊&#xff0c;养号、测评都需要代理IP的帮助。那么应该使用什么代理IP呢&#xff1f;如何使用&#xf…

JS-02-javaScript快速入门

一、javaScript代码的编写位置 JavaScript代码可以直接嵌在网页的任何地方&#xff0c;但是一般&#xff0c;我们用如下编写方式。 1-1、直接写到HTML文件中 通常我们都把JavaScript代码放到<head>中&#xff0c;由<script>...</script>包含的代码就是Java…

【深度学习】1. 深度学习概述

感知器模型 人脑中的神经元:一个神经元通常具有多个树突&#xff0c;主要用来接受传入信息;而轴突只有一条&#xff0c;轴突尾端有许多轴突末梢可以给其他多个神经元传递信息。轴突末梢跟其他神经元的树突产生连接&#xff0c;从而传递信号。 而在计算机的神经网络中&#xff…

985硕的4家大厂实习与校招经历专题分享(part2)

我的个人经历&#xff1a; 985硕士24届毕业生&#xff0c;实验室方向:CV深度学习 就业&#xff1a;工程-java后端 关注大模型相关技术发展 校招offer: 阿里巴巴 字节跳动 等10 研究生期间独立发了一篇二区SCI 实习经历:字节 阿里 京东 B站 &#xff08;只看大厂&#xff0c;面试…

Mysql - is marked as crashed and should be repaired

概述 上周发生了一个Mysql报错的问题&#xff0c;今天有时间整理一下产生的原因和来龙去脉&#xff0c;Mysql的版本是5.5,发生错误的表存储引擎都是MyISAM,产生的报错信息是Table xxxxxx is marked as crashed and should be repaired。 定位问题 产生的后果是Nginx服务没有…

C++入门知识点

文章目录 一、C的域作用限定符1.1全局域1.2限定域作用范围 二、C的命名空间域2.1单个命名空间的变量访问和单个不同命名空间的相同变量名的访问2.2命名空间的嵌套调用 三、C的流插入、流提取操作符四、C的缺省参数4.1函数的全缺省4.1函数的部分缺省 五、C的函数重载5.1函数重载…

this关键字

this关键字 this 是 Java 的一个关键字&#xff0c;表示某个对象 this 可以出现在构造方法、实例方法中&#xff0c;但不可以出现在类方法中 出现在构造方法中&#xff0c;代表使用该构造方法创建的对象出现在实例方法中&#xff0c;代表正在调用该方法的当前对象 一、构造…

Docker-容器网络互联

目录 1 前言 2 常用指令 3 实现容器互联 3.1 自定义网络 3.2 让容器连接创建的网络 3.2.1 容器创建后连接网络 3.2.2 容器创建时连接网络 3.3 尝试使用容器名访问(测试) 1 前言 在默认情况下&#xff0c;docker中的容器都是连接到一个虚拟的网桥上的&#xff0c;这为独…

关于yolov8的DFL模块(pytorch以及tensorrt)

先看代码 class DFL(nn.Module):"""Integral module of Distribution Focal Loss (DFL).Proposed in Generalized Focal Loss https://ieeexplore.ieee.org/document/9792391"""def __init__(self, c116):"""Initialize a convo…

【Web前端入门学习】—CSS

目录 CSS简介CSS语法CSS三种导入方式CSS选择器元素选择器&#xff08;标签选择器&#xff09;类选择器ID选择器通用选择器子元素选择器后代选择器&#xff08;包含选择器&#xff09;并集选择器&#xff08;兄弟选择器&#xff09;伪类选择器伪元素选择器 CSS常用属性盒子模型网…

电脑工作电压是多少你要看看光驱电源上面标的输入电压范围

要确定电脑的工作电压&#xff0c;必须查看电源上标注的输入电压范围。 国内法规规定民用220V电压范围为10%-15%&#xff0c;也就是说通信220V电压正常范围为187--242V&#xff0c;供电设备一般为180V。 --250V电压范围&#xff0c;即正常情况下电脑电源电压不低于187V即可工作…

css相邻元素边框重合问题,解决方案

1、如下图所示&#xff0c;在给元素设置边框后&#xff0c;相邻元素会出现重合的问题 2、解决方案 给每个元素设置margin-top以及margin-left为负的边框 <div style"width: 300px;display: flex;flex-wrap: wrap;margin-top: 50px;"><div style"border…

【数据结构】二、线性表:5.静态链表的定义及其基本操作(定义、初始化、插入、查找、删除、遍历、长度、特点)

文章目录 5.静态链表5.1定义5.2初始化5.3插入5.4查找5.5删除5.6遍历5.7长度5.8特点 5.静态链表 静态链表是使用数组来模拟链表结构的一种数据结构&#xff0c;用数组的方式实现的链表。 它与传统链表的区别在于&#xff0c;静态链表使用数组保存节点&#xff0c;每个节点包括…

mac系统Idea登录codeium不跳转,报错faild download language server

问题描述 idea通过插件中心安装Codeium以后&#xff0c;登录无法正常跳转到登录页&#xff0c;等待一段时间&#xff0c;右下角图标报错**“faild download language server”** 解决方案 根据上面的报错&#xff0c;是没有成功下载“language_server_macos_x64“&#xff0…