系列十一、索引

2023-12-19

一、索引

1.1、概述

索引(index )是帮助 MySQL 高效获取数据的有序数据结构  。在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据, 这样就可以在这些数据结构上实现高级查找算法,这种数据结构就是索引。

1.2、演示

1.2.1、无索引情况

user表结构如下:

查询语句: select * from user where age = 45;

执行结果:

分析: 在无索引的情况下,需要从第一行开始扫描,一直扫描到最后一行,这种扫描称之为全表扫描,性能很低。

1.2.2、有索引情况

如果我们针对于这张表建立了索引,假设索引结构就是二叉树,那么也就意味着,会对 age 这个字段建立一个二叉树的索引结构。

此时,我们再次执行select * from user where age = 45;只需要扫描3次就可以找到数据了,极大的提高的查询的效率。

1.3、索引的优势 & 劣势

1.4、索引结构

1.4.1、概述

MySQL的索引是在存储引擎层实现的,不同的存储引擎有不同的索引结构,MySQL中支持的所有的索引结构主要包含以下几种:

1.4.2、存储引擎对索引结构的支持

注意事项: 我们平常所说的索引,如果没有特别指明,都是指B+树结构的索引。

1.5、常见索引

1.5.1、二叉树

(1) 假如说 MySQL 的索引结构采用二叉树的数据结构,比较理想的结构如下:

(2) 如果主键是顺序插入的,则会形成一个单向链表,结构如下:

小总结:使用二叉树作为索引结构,会存在如下缺点:

(1)顺序插入时,会形成一个链表,查询性能大大降低;

(2)大数据量情况下,层级较深,检索速度慢;

(3)红黑树

概述: 红黑树是一颗自平衡二叉树,即使是顺序插入数据,最终形成的数据结构也是一颗平衡的二叉树,结构如下:

存在的问题:红黑树虽然是一颗自平衡二叉树,但是在大数据量的前提下,依然存在层级较深,检索速度慢的问题。所以在MySQL的索引结构中,并没有选择二叉树或者红黑树,而是选择的B+Tree索引。

1.5.2、B-Tree

概述:

B-Tree是一种多叉路衡查找树,相当于二叉树,B树的每个节点可以有多个分支,即:多叉。以一颗最大度数为5阶的B-Tree为例,那么这个树的每个节点最多可以存储5个key,5个指针,大致如下:

说明 :树的度数指的是一个节点的子节点个数;

可视化网站 https://www.cs.usfca.edu/~galles/visualization/BTree.html

插入一组数据 100 65 169 368 900 556 780 35 215 1200 234 888 158 90 1000 88 120 268 250

特点:

(1)5阶的B树,每一个节点最多存储4个key,对应5个指针;

(2)一旦节点存储的key的数量达到5,就会裂变,中间元素向上分裂;

(3)在B树中,非叶子节点和叶子节点都会存储数据;

1.5.3、B+Tree

概述:

B+Tree是B-Tree的一种变种,我们以一颗最大度为4阶的B+Tree为例,来看一下大致的结构示意图,如下:

分析: 从上图的B+Tree的结构示意图,可以得出如下结论:

(1)绿色框框起来的部分,是索引部分,仅仅起到索引数据的作用,不存储数据;

(2)红色框框起来的部分,是数据存储部分,在其叶子节点中存储具体的数据;

可视化网站: https://www.cs.usfca.edu/~galles/visualization/BPlusTree.html

插入一组数据 100 65 169 368 900 556 780 35 215 1200 234 888 158 90 1000 88 120 268 250

B-Tree vs B+Tree

通过上述的在线演示,可以看到B+Tree与B-Tree相比,主要有以下3点区别:

(1)所有的数据都会出现在叶子节点;

(2)叶子节点形成一个单向链表;

(3)非叶子节点仅仅起到索引数据的作用,具体的数据都是在叶子节点存放的;

MySQL优化后的B+Tree索引结构:

MySQL的索引结构对经典的B+Tree索引进行了优化,在原B+Tree的基础上,增加一个指向相邻叶子节点的链表指针,就形成了带有顺序指针的B+Tree,提高区间访问的性能,利于排序,结构如下:

1.5.5、Hash

概述:

哈希索引就是采用一定的hash算法,将键值计算成新的hash值,映射到对应槽位上,然后存储在hash表中,结构如下:

说明:

如果两个或者多个键值,经过hash计算映射到同一个槽位上了,它们就产生了hash冲突(也称为hash碰撞),可以通过链表的形式来解决。

特点:

(1)hash索引只支持精确查找,不支持范围查询;

(2)无法利用索引完成排序工作;

(3)查询效率高,通常只需要一次检索就可以了,效率通常高于B+Tree索引;

存储引擎支持:

在MySQL中,虽然支持hash索引的存储引擎是Memory,但是InnoDB引擎具有自适应hash的功能,hash索引是InnoDB存储引擎根据B+Tree索引在指定条件下自动构建的。

面试题:为什么InnoDB存储引擎选择使用B+Tree索引结构?

(1)相对于二叉树,B+Tree索引结构的层级更少,搜索效率更高;

(2)相对于B-Tree,无论是叶子节点还是非叶子节点都保存数据,这会导致一页中存储的键值减少,指针也跟着随之减少,保存同样大小的数据,增加了树的高度,导致查询效率降低;

(3)相对hash索引,B+Tree支持范围查询及排序操作;

1.6、索引分类

1.6.1、按照类型分类

在MySQL数据库中,根据索引的具体类型不同,可以分为如下几类,即:

1.6.2、按照索引的存储形式分类

在InnoDB存储引擎中,根据索引的存储形式,又可以分为以下两种:

聚集索引选取规则:

(1)如果存在主键,那么主键索引就是聚集索引;

(2)如果不存在主键,则使用第一个唯一索引作为聚集索引;

(3)如果没有主键+没有唯一索引,则InnoDB会自动的生成一个rowid作为隐藏的聚集索引;

聚集索引和二级索引的结构如下:

结论:

(1)聚集索引的叶子节点挂的是这一行的数据;

(2) 二级索引的叶子节点挂的是该字段值对应的主键值

查找过程:

假设我们执行如下sql语句,那么具体的执行过程是什么样的呢?

具体情况如下:

(1)由于是根据name字段进行查询,所以先根据name='Arm'到name字段的二级索引中进行匹配查找,但是在二级索引中只找到了Arm对应的主键值10;

(2)由于查询返回的数据是所有字段,所以此时还需要根据主键值10到聚集索引中查找10对应的记录,最终找到10对应的行row;

(3)拿到这一行的数据,返回。

回表查询:

向上述先到二级缓存中查找数据,找到主键值,然后再到聚集索引中根据主键值获取数据的方式,称之为回表查询。

1.7、索引实战

1.7.1、前置说明

前边的系列文章中是基于Linux中的MySQL进行案例演示的,为了后续测试百万条数据的sql性能分析,接下来的案例将会在Windows的MySQL中进行演示,MySQL版本要求需在8.0以上,我的MySQL版本信息如下:

1.7.2、数据初始化

链接:https://pan.baidu.com/s/1TGLDb9awudyjhZDcu0HNfQ?pwd=yyds 
提取码:yyds 

百万数据初始化:

前置说明

-- 查询是否开启了加载本地文件(默认没有开启,需要开启才能执行load指令)
show variables like 'local_infile';
-- 开启加载本地文件
set global local_infile=on;
-- 执行load指令(依次执行tb_sku1、tb_sku2、...tb_sku5,执行一个脚本差不多耗费100s,耐心等待即可!)
load data local infile 'D:/temp/tb_sku1.sql' into table `tb_sku` fields terminated by ',' lines terminated by '\n';

1.7.3、案例

创建索引:

(1)name字段为姓名字段,该字段的值可能会重复,为该字段创建普通索引;

create index idx_user_name on user(name);

(2)phone字段为手机号码,非空且唯一,为该字段创建唯一索引

create unique index idx_user_phone on user(phone);

(3)为profession、age、status字段创建联合索引;

create index idx_user_profession_age_status on user(profession,age,status);

(4)为email字段建立普通索引

create index idx_user_email on user(email);

查看索引: 查看user表中所有的索引数据;

show index from user;

1.8、SQL性能分析

1.8.1、SQL执行频率

概述:

MySQL客户端连接成功后,通过show [session|global] status 命令可以查询服务器的状态信息,通过如下指令可以查看当前数据库的insert、update、delete、select的访问频次。

查看当前数据库以哪种业务为主:

show session status like 'Com_______';

通过上述指令的执行结果,可以分析出当前业务是以查询为主还是以增删改为主,从而为数据库的优化提供参考依据,如果是以增删改为主,就可以考虑不对其进行索引优化了,如果是以查询为主,那么就要考虑对索引进行优化了。

说明:

Com_insert:插入次数

Com_update:更新次数

Com_delete:删除次数

Com_select:查询次数

1.8.2、慢查询日志

概述:

慢查询日志记录了执行时间超过指定参数(long_query_time,单位:秒)的所有SQL语句的日志。MySQL默认的慢查询日志没有开启,我们可以看一下系统变量中该参数对应的值是什么:

(1)查看慢SQL配置:show variables like '%slow_query_log%';

(2)开启慢SQL配置: Windows ===> my.ini、Linux ===> /etc/my.cnf

添加如下内容:

# 开启MySQL慢查询日志开关
slow_query_log=1
# 设置慢日志的时间为2秒,SQL语句执行时间超过2秒,就会视为慢查询,记录慢查询日志
long_query_time=2
(3)重启MySQL
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

系列十一、索引 的相关文章

随机推荐

  • optisystem案例解析》好书分享

    目 录 安装OptiSystem 简介 快速入门 案例1 发射机 外调制激光 案例2 子系统 分层模拟 案例3 光学系统 WDM设计 案例4 参数扫描 BERx输入功率 案例5 双向模拟 使用多次迭代 案例6 时间驱动模拟 单独采样 案例7
  • 计算机SSM毕设选题 协同过滤算法的电影推荐系统

    开发语言 Java Java开发工具 JDK1 8 后端框架 SSM 前端 Vue 数据库 MySQL5 7和Navicat管理工具结合 服务器 Tomcat8 5 开发软件 IDEA Eclipse 是否Maven项目 是 目录 一 项目
  • Selenium+Jave—Window文件窗口+比对文件

    新生一学期敲70万行代码 华为上海青浦 途虎一面凉经 途虎养车前端一面面经 途虎一面凉经 前端 途虎养车二面 途虎校招前端一面面经 中石油昆仑数智产品经理岗 中石油昆仑数智 数据分析工程师 华为上海青浦 上海银行背调 回暖分析 战绩结算 o
  • Uniapp上传下载文件-不限制文件类型-附详细代码解析

    Uniapp上传下载文件 不限制文件类型 1 知识小课堂 1 1 Uniapp简介 1 2 文件上传 1 3 文件下载 2 Uniapp上传文件 3 Uniapp 下载文件 1 知识小课堂 1 1 Uniapp简介 UniAp
  • 黑马程序员《PHP基础案例教程》第2版课后练习—第04章

    第4章课后练习 答案均参考教材官方发布的PPT 以下是下载PPT的页面 人民邮电出版社教育社区 PHP基础案例教程 第2版 图书 人邮教育社区 一 填空题 1 数组分为索引数组和 关联数组 2 使用短数组方式定义数组的语法是 数组元素使用
  • CSDN:黑马程序员《PHP基础案例教程》第2版课后练习—第05章

    第5章课后练习 答案均参考教材官方发布的PPT 以下是下载PPT的页面 人民邮电出版社教育社区 PHP基础案例教程 第2版 图书 人邮教育社区 一 填空题 1 在运行PHP文件时 如果PHP语句遗漏了分号 属于 语法 错误 2 在PHP程序
  • 低代码企业级PMO项目管理系统,360度全景透视企业管理视角

    在一个崇高的目标支持下 不停地工作 即使慢 也一定会获得成功 爱因斯坦 前情概要 企业级PMO项目管理业务是行业里相对成熟和规范的业务 拥有众多商业套件和标准产品 然而随着企业数字化建设进入深水区 站在甲方角度进行项目管理的业务视角 精细化
  • 得帆信息创始人-张桐,受邀出席 BV百度风投AIGC主题论坛

    近日 得帆信息创始人兼CEO张桐 作为百度风投被投代表企业创始人受邀出席 向未来 共成长 BV百度风投AIGC主题论坛 与包括上海市徐汇区相关部门领导 百度集团相关事业部负责人及代表 以及来自国寿资本 中网投 麦顿投资的投资人 BV百度风投
  • Typora+Picgo(正常) 却上传图片失败问题解决思路和办法

    报错信息 在typora中粘贴图片时报错 显示上传图片失败 有点奇怪 而我确定我的picgo正常且通过了测试 那我们就去看日志 跟踪排查问题在哪里 我的picgo日志文件路径在 D user username Application Dat
  • Vue中英文翻译小结

    背景 时局艰难 后端开发被强制写了vue 这不有个需求是中英文翻译 特此记录下 该怎么个翻译法子 先引入全局的路由国际化文件 zh js 和 en js 1 关于插值表达Button里面 t reinsop common back 2 关于
  • onvif协议笔记

    一 简介 ONVIF官网 ONVIF协议网络摄像机 IPC 客户端程序开发 1 专栏开篇 onvif协议开发 二 gSOAP gsoap官网 1 下载和编译 下载地址 bin sh 指定源码目录 解压源码 GSOAP SRC gsoap 2
  • nacos启动 java.net.UnknownHostException: jmenv.tbsite.net

    只做记录 地址在这 windows 双击执行startup cmd文件 默认是以集群方式启动nacos 由于只想用单体的并没有配置集群相关的属性 所以无法启动 解决方式1 在命令行输入startup m standalone以单机模式启动就
  • 冬日路亚,寒冬中的收获【钓鱼博客】12.17日

    12月17日 南京 桦树钓场 晴 气温 零下4度到0度 虽屋外寒风刺骨 但钓鱼佬实在是压不住心里想钓鱼的冲动 我还是出发了 才抛几竿 出线孔和鱼竿导线孔结冰 以上阿尔法渔轮的导线规由于线上有水导致结冰冻上了 中鱼出线视频 轮子咔咔出线 渔获
  • 黑马程序员《PHP基础案例教程》第2版课后练习—第03章

    第3章课后练习 答案均参考教材官方发布的PPT 以下是下载PPT的页面 人民邮电出版社教育社区 PHP基础案例教程 第2版 图书 人邮教育社区 一 填空题 1 定义函数使用的关键字为 function 2 用于对字符串中的某些字符进行替换操
  • 密码学上的经典瞬间:如果当时有Python

    提到 安全 首先想到的一定是加密 在如今的互联网环境中 信息加密无处不在 我们早已习惯 甚至毫无感觉 比如 通过https协议访问的各个网站的内容 QQ 微信等聊天工具之间互相发送的信息等等 都是经过加密处理的 前几天看了一篇介绍密码学历史
  • Linux CentOS7安装harbor

    1 下载harbor离线包 wget https github com goharbor harbor releases download v2 4 2 harbor offline installer v2 4 2 tgz 2 解压安装
  • Fortinet在“IDC MarketScape: 中国软件定义广域网基础设施2023年厂商”评估中位居“领导者”类别

    近日 IDC MarketScape 中国软件定义广域网基础设施2023年厂商评估 正式发布 该报告通过 IDC MarketScape 厂商评估模型对中国SD WAN基础设施厂商进行了评估 Fortinet 在该报告中位居 领导者 类别
  • 常见的6种软件测试用例设计方法

    常见的软件测试用例设计方法 个人认为主要是下面这6种 流程图法 也叫场景法 等价类划分法 边界值分析 判定表 正交法 错误推测法 这6种常见方法中 我分别按照定义 应用场景 使用步骤 案例讲解这4个部分进行讲解 所以本文行文结构如下 每种用
  • 【正式服部署】安装Nginx

    正式服部署 安装Nginx 千寻简笔记介绍 千寻简文库已开源 Gitee与GitHub搜索 chihiro doc 包含笔记源文件 md 以及PDF版本方便阅读 文库采用精美主题 阅读体验更佳 如果文章对你有帮助请帮我点一个 Star 更新
  • 系列十一、索引

    一 索引 1 1 概述 索引 index 是帮助 MySQL 高效获取数据的有序数据结构 在数据之外 数据库系统还维护着满足特定查找算法的数据结构 这些数据结构以某种方式引用 指向 数据 这样就可以在这些数据结构上实现高级查找算法 这种数据