MySQL知识点总结(一)——一条SQL的执行过程、索引底层数据结构、一级索引和二级索引、索引失效、索引覆盖、索引下推

本文主要是介绍MySQL知识点总结(一)——一条SQL的执行过程、索引底层数据结构、一级索引和二级索引、索引失效、索引覆盖、索引下推,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

MySQL知识点总结(一)——一条SQL的执行过程、索引底层数据结构、一级索引和二级索引、索引失效、索引覆盖、索引下推

  • 一条SQL的执行过程
  • 索引底层数据结构
    • 为什么不使用二叉树?
    • 为什么不使用红黑树?
    • 为什么不使用hash表?
    • 为什么不使用b-tree?
  • 一级索引和二级索引
  • 索引失效
  • 索引覆盖
  • 索引下推

一条SQL的执行过程

在这里插入图片描述

  • 客户端:用于向服务端发起sql查询或更新请求,MySQL自带的命令行客户端、MySQL的JDBC客户端等都是。
  • 连接器:用于接收客户端的连接,并进行身份认证、查询当前账号拥有的权限。
  • 查询缓存:MySQL服务端会将一条SQL的查询结果缓存缓存起来,下一次再执行相同的sql时,就可以直接从缓存中取。但是一旦对应的库表发生了更新,缓存将会被清空,因此只适用于更新频率不高的场景,MySQL8.0以上的版本已经将其去除。
  • 分析器:对SQL进行词法分析和语法发现,就是分析我们的这个SQL要干啥。
  • 优化器:对我们的SQL进行优化,选取使用的索引,生成执行计划。
  • 执行器:调用执行引擎的接口进行SQL查询或更新。

索引底层数据结构

MySQL索引的底层数据结构是B+树。

在这里插入图片描述

B+树是多路平衡树(B-tree)的一个变种,非叶子节点只存放主键和到下一级节点的指针,叶子节点存放主键和主键对应的数据行记录,叶子节点通过指针进行连接,形成一个双向链表,还有一个头指针和尾指针分别指向链表头节点和尾节点。在MySQL的b+tree中,一个索引页是16KB。

为什么不使用二叉树?

首先我们要明白一点,MySQL中的索引页是存储在磁盘中的,每次读取一个索引页,都是一次磁盘读取,会有磁盘寻址的开销,因此MySQL应该选取一种数据结构,可以让它尽量少的去读取磁盘,才适合作为存储索引的数据结构。

因为二叉树每个节点只有两个出路,树高较高,而B+树是多路平衡树,每个节点有多个出路,树高较矮,这意味着如果用二叉树作为索引的数据结构的话,磁盘寻址的次数会比使用B+树时多,性能不如B+树。

并且,在极端情况下,二叉树会退化成链表,比如id等于1、2、3、4、5、6、7的七条数据按顺序插入,最终二叉树的结果就变成了下图这个样子。

在这里插入图片描述

为什么不使用红黑树?

红黑树解决了二叉树极端情况退化成链表的问题,但是它没有解决树高较高的问题,因为红黑树也是一个二叉树的数据结构。

在这里插入图片描述

为什么不使用hash表?

hash表在插入和等值查询时非常快,可以做到O(1)的时间复杂度。但是hash表的原理是通过hash函数根据key算出一个hash值,然后通过hash值与hash表中的数组长度取模后,进行散列存储的,数据之间不存在顺序性,因此做索引范围查询时需要进行全表扫描,性能是比较低的。

在这里插入图片描述
而B+树是按顺序排好序的,并且索引页之间有双向指针,还有头指针和尾指针,范围查询非常方便。

为什么不使用b-tree?

B树是多路平衡树,分叉比二叉树和红黑树多,因此树高会比二叉树和红黑树矮。但是B树的非叶子节点也存放数据,而MySQL的索引页又固定是16KB,因此节点分叉较B+树少,树高比B+树高。此外,B树的叶子节点是没有双向链表连接的,因此范围查询的性能不如B+树。

在这里插入图片描述

一级索引和二级索引

一级索引也叫主键索引,是以主键作为索引键的索引,在B+树中通过主键进行排序。
在这里插入图片描述
二级索引是非主键索引,是以非主键的字段作为索引键进行排序,比如我们以上面的表为例,在age字段上建立一个二级索引,则效果如下图。

在这里插入图片描述

二级节点的叶子节点不存储行记录,而是存储索引建(age字段)和主键(id),当通过二级索引进行搜索时,会先从二级索引找到对应的主键,再通过主键在一级索引中进行查找,这个过程叫做回表。比如我们要通过二级索引查找age=60的这一条数据,则整个过程如下。

在这里插入图片描述

这个回表的过程是有性能开销的,如果MySQL判断走二级索引的代价比较大,不如全表扫描,就会放弃二级索引进行全表扫描。回表一般是因为我们建立二级索引时只包含一个索引键,没有包含要查询的其他字段,如果我们建立二级索引时,连同其他需要查询返回的字段一起建立一个二级联合索引,使得需要查询返回的字段在二级索引叶子节点中都有,MySQL就不会回表,这时候二级索引一般都会生效。

索引失效

索引失效是指由于SQL语句编写不规范(或其他原因)导致MySQL不走已经建立的索引进行查询,以下几种情况都会造成索引失效。

在这里插入图片描述

索引覆盖

索引覆盖是一种优化二级索引回表查询的手段,在建立索引时,原先的索引键连同最终需要查询返回的字段一起组成一个联合索引。这样,MySQL通过二级索引进行查询时,发现二级索引的叶子节点已经包含了所有需要查询返回的字段,就不会再回表查询,这样查询性能就会大大提高,原本由于大量回表而导致二级索引失效,通过这种优化手段,会使得MySQL会选择这个二级索引进行查询。

在这里插入图片描述

索引下推

在老版本的MySQL中,如果联合索引查询使用了范围查询,会使得联合索引中范围查询的字段的后续字段失效。比如我们有一张t_user表,有四个字段:“id(主键)、name、age、phone”。现在我们有一个sql:“select name, age, phone, where name like ‘黄%’ and age > 20;”。我们建立了一个联合索引(name,age),如果MySQL查询走了这个索引,那么MySQL5.6以前的版本是这样的:

在这里插入图片描述

新版本(5.6之后)的MySQL则通过索引下推进行优化,MySQL在通过二级索引中的name字段进行模糊匹配查询后,会利用二级索引中的第二个字段age进行条件判断来做进一步的筛选过滤,过滤掉不满足“age > 20”这个条件的id,这样可以减少回表的次数提升查询性能。

在这里插入图片描述

这篇关于MySQL知识点总结(一)——一条SQL的执行过程、索引底层数据结构、一级索引和二级索引、索引失效、索引覆盖、索引下推的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/655323

相关文章

Spring boot整合dubbo+zookeeper的详细过程

《Springboot整合dubbo+zookeeper的详细过程》本文讲解SpringBoot整合Dubbo与Zookeeper实现API、Provider、Consumer模式,包含依赖配置、... 目录Spring boot整合dubbo+zookeeper1.创建父工程2.父工程引入依赖3.创建ap

SQL server数据库如何下载和安装

《SQLserver数据库如何下载和安装》本文指导如何下载安装SQLServer2022评估版及SSMS工具,涵盖安装配置、连接字符串设置、C#连接数据库方法和安全注意事项,如混合验证、参数化查... 目录第一步:打开官网下载对应文件第二步:程序安装配置第三部:安装工具SQL Server Manageme

C#连接SQL server数据库命令的基本步骤

《C#连接SQLserver数据库命令的基本步骤》文章讲解了连接SQLServer数据库的步骤,包括引入命名空间、构建连接字符串、使用SqlConnection和SqlCommand执行SQL操作,... 目录建议配合使用:如何下载和安装SQL server数据库-CSDN博客1. 引入必要的命名空间2.

Linux下进程的CPU配置与线程绑定过程

《Linux下进程的CPU配置与线程绑定过程》本文介绍Linux系统中基于进程和线程的CPU配置方法,通过taskset命令和pthread库调整亲和力,将进程/线程绑定到特定CPU核心以优化资源分配... 目录1 基于进程的CPU配置1.1 对CPU亲和力的配置1.2 绑定进程到指定CPU核上运行2 基于

全面掌握 SQL 中的 DATEDIFF函数及用法最佳实践

《全面掌握SQL中的DATEDIFF函数及用法最佳实践》本文解析DATEDIFF在不同数据库中的差异,强调其边界计算原理,探讨应用场景及陷阱,推荐根据需求选择TIMESTAMPDIFF或inte... 目录1. 核心概念:DATEDIFF 究竟在计算什么?2. 主流数据库中的 DATEDIFF 实现2.1

MySQL 多列 IN 查询之语法、性能与实战技巧(最新整理)

《MySQL多列IN查询之语法、性能与实战技巧(最新整理)》本文详解MySQL多列IN查询,对比传统OR写法,强调其简洁高效,适合批量匹配复合键,通过联合索引、分批次优化提升性能,兼容多种数据库... 目录一、基础语法:多列 IN 的两种写法1. 直接值列表2. 子查询二、对比传统 OR 的写法三、性能分析

MySQL中的LENGTH()函数用法详解与实例分析

《MySQL中的LENGTH()函数用法详解与实例分析》MySQLLENGTH()函数用于计算字符串的字节长度,区别于CHAR_LENGTH()的字符长度,适用于多字节字符集(如UTF-8)的数据验证... 目录1. LENGTH()函数的基本语法2. LENGTH()函数的返回值2.1 示例1:计算字符串

mybatis执行insert返回id实现详解

《mybatis执行insert返回id实现详解》MyBatis插入操作默认返回受影响行数,需通过useGeneratedKeys+keyProperty或selectKey获取主键ID,确保主键为自... 目录 两种方式获取自增 ID:1. ​​useGeneratedKeys+keyProperty(推

浅谈mysql的not exists走不走索引

《浅谈mysql的notexists走不走索引》在MySQL中,​NOTEXISTS子句是否使用索引取决于子查询中关联字段是否建立了合适的索引,下面就来介绍一下mysql的notexists走不走索... 在mysql中,​NOT EXISTS子句是否使用索引取决于子查询中关联字段是否建立了合适的索引。以下

Java通过驱动包(jar包)连接MySQL数据库的步骤总结及验证方式

《Java通过驱动包(jar包)连接MySQL数据库的步骤总结及验证方式》本文详细介绍如何使用Java通过JDBC连接MySQL数据库,包括下载驱动、配置Eclipse环境、检测数据库连接等关键步骤,... 目录一、下载驱动包二、放jar包三、检测数据库连接JavaJava 如何使用 JDBC 连接 mys