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

news2024/10/22 8:05:07

文章目录

  • 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.coloradmin.cn/o/1498756.html

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

相关文章

uniapp——nextTick(vue3)数据更新完之后加载

说明 将回调推迟到下一个 DOM 更新周期之后执行。在更改了一些数据以等待 DOM 更新后立即使用它。 代码 <view class"tabBox"><scroll-view scroll-x"true" :scroll-with-animation"true"><view class"box"><…

利用“定时执行专家”循环执行BAT、VBS、Python脚本——含参数指定功能

目录 一、软件概述 二、VBS脚本执行设置 三、触发器设置 四、功能亮点 五、总结 在自动化办公和日常计算机任务管理中&#xff0c;定时执行脚本是一项非常重要的功能。今天&#xff0c;我将为大家带来一款名为“定时执行专家”的软件的评测&#xff0c;特别是其定时执行VB…

leetCode刷题 5.最长回文子串

目录 1. 思路 2. 解题方法 3. 复杂度 4. Code 题目&#xff1a; 给你一个字符串 s&#xff0c;找到 s 中最长的回文子串。 如果字符串的反序与原始字符串相同&#xff0c;则该字符串称为回文字符串。 示例 1&#xff1a; 输入&#xff1a;s "babad" 输出&#x…

3.7 day2 Free RTOS

使用ADC采样光敏电阻数值&#xff0c;如何根据这个数值调节LED灯亮度。2.总结DMA空闲中断接收数据的使用方法 while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */adc_value HAL_ADC_GetValue(&hadc);TIM3->CCR3 adc_value * 999 / 4095;printf("%d …

Docker网络+原理+link+自定义网络

目录 一、理解Docker网络 1.1 运行tomcat容器 1.2 查看容器内部网络地址 1.3 测试连通性 二、原理 2.1 查看网卡信息 2.2 再启动一个容器测试网卡 2.3 测试tomcat01 和tomcat02是否可以ping通 2.4 只要删除容器,对应网桥一对就没了 2.5 结论 三、--link 3.…

探索考古文字场景,基于YOLOv7【tiny/l/x】不同系列参数模型开发构建文本考古场景下的甲骨文字符图像检测识别系统

甲骨文是一种非常历史悠久的古老文字&#xff0c;在前面我们基本上很少有涉及这块的内容&#xff0c;最近正好在做文字相关的项目开发研究&#xff0c;就想着基于甲骨文的场景来开发对应的检测识别系统&#xff0c;首先看下实例效果&#xff1a; YOLOv7是 YOLO 系列最新推出的Y…

dubbo3适配springboot2.7.3

版本详细 <dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo</artifactId><version>3.0.3</version> </dependency><parent><groupId>org.springframework.boot</groupId><artifactId&…

css 用flex做成田字型

哈喽&#xff0c;各位小伙伴&#xff01;今天给大家来css控制div完成田字型样式&#xff0c;来&#xff0c;看看下面的效果图&#xff1a; 一看就知道你们想要代码了&#xff0c;不急。代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head>&…

c++ 11 新特性 不同数据类型之间转换函数之reinterpret_cast

一.不同数据类型之间转换函数reinterpret_cast介绍 reinterpret_cast是C中的一种类型转换操作符&#xff0c;用于执行低级别的位模式转换。具体来说&#xff0c;reinterpret_cast可以实现以下功能&#xff1a; 指针和整数之间的转换&#xff1a;这种转换通常用于在指针中存储额…

【考研数学】武忠祥各阶段用书搭配+学习包

25考研数学全流程规划&#xff01;别等到二战了才知道这样学 本人属于基础很差相当于是零基础的考研党&#xff0c;经过一年备考成功上岸 中间花费了很多时间在考研数学备考信息检索上&#xff0c;写下这篇希望能帮助基础不好的学弟学妹们多节约一些时间复习&#xff01; 25…

容器+虚拟机双引擎,ZStack Edge云原生超融合打通业务最后一公里

企业数字化转型的焦点正在发生变化&#xff0c;云基础设施由资源到应用&#xff0c;数据中心从核心到边缘。面向云原生趋势&#xff0c;围绕应用升级&#xff0c;新一代超融合产品——云原生超融合应运而生。 云原生与边缘计算趋势催生云原生超融合 当前&#xff0c;企业客户…

【CSP试题回顾】201409-3-字符串匹配

CSP-201409-3-字符串匹配 关键点&#xff1a;<string>库函数的使用 length() 或 size(): 返回字符串的长度。 empty(): 检查字符串是否为空。 append() 或 : 向字符串的末尾添加字符或另一个字符串。 insert()在字符串的指定位置插入另一个字符串或字符。 std::str…

Docker-容器网络互联

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

web服务之虚拟主机功能

华子目录 概述基于IP地址的虚拟原理实验 基于不同端口号的虚拟主机原理实验 基于域名的虚拟主机原理域名解析实验 概述 如果每台运行 Linux 系统的服务器上只能运行一个网站&#xff0c;那么人气低、流量小的草根站长就要被迫承担着高昂的服务器租赁费用了&#xff0c;这显然也…

使用Python制作自己的wheel文件

平时自己利用Python制作一个个小工具后想分享给别人&#xff0c;但又嫌分享一堆项目代码很麻烦&#xff0c;那么你可以考虑将自己的项目打包成一个wheel文件&#xff0c;别人拿到文件后只需pip install安装即可使用&#xff0c;非常方便。 在上一篇博文中&#xff0c;利用nvid…

01、python_爬虫的相关概念

一、什么是爬虫&#xff1f; 爬虫是网络爬虫的简称&#xff0c;指的是一种自动化程序&#xff0c;用于在互联网上抓取信息。爬虫的核心工作包括爬取网页、解析数据和存储数据。 通俗来说就是&#xff1a;通过一个程序&#xff0c;根据url(http://taobao.com)进行爬取网页&…

第九届多媒体系统和信号处理国际会议(ICMSSP 2024)即将召开!

2024年第九届多媒体系统和信号处理国际会议&#xff08;ICMSSP 2024&#xff09;将在5月24-26日在泰国曼谷举行。ICMSSP 2024旨在展示多媒体系统和信号处理等相关主题的最新研究和成果&#xff0c;为不同领域的专家代表提供了面对面交流新想法以及应用经验的机会&#xff0c;建…

从零搭建React18.2+ReactRoute6.22+TS5+RTK2.2搭配antd5+antd-style书写All in Js完整体验项目规范

1. 使用CRA创建项目 全局设置npm淘宝镜像源 npm config set registry https://registry.npmmirror.com -g使用最新版create-react-app初始化项目结构 npx create-react-app custom-template --template typescript初始化项目之后在package.json文件中配置使用node>18.0.0…

鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:CalendarPicker)

日历选择器组件&#xff0c;提供下拉日历弹窗&#xff0c;可以让用户选择日期。 说明&#xff1a; 该组件从API Version 10开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 子组件 无 接口 CalendarPicker(options?: CalendarOptions) …

构建读写分离的数据库集群

目录 1. 基础环境配置 &#xff08;1&#xff09;修改主机名 &#xff08;2&#xff09;编辑hosts文件 &#xff08;3&#xff09;配置Yum安装源 &#xff08;4&#xff09;安装JDK环境 2. 部署MariaDB主从数据库集群服务 &#xff08;1&#xff09;安装MariaDB服务 &a…