《MySQL45讲》笔记—索引
索引
索引是为了提高数据查询效率,就像书的目录一样。如下图,索引和数据就是位于存储引擎中:
索引常见模型
哈希表
以键值对存储的数据结构。适用于只有等值查询的场景。
有序数组
在等值查询和范围查询场景中性能都特别优秀。但是有序数组索引只适用于静态存储引擎,如果需要更新数据的话就成本太高了。
二叉树
每个节点的左儿子小于父节点,父节点又小于右儿子。二叉树的搜索效率是最高的,但是实际上大多数的数据库存储并不使用二叉树,因为索引不止存在内存中,还要写道磁盘上。一般使用N叉树,这个N取决于数据块的大小。
数据库发展到今天,跳表、LSM树等数据结构也被应用于引擎设计中,但是数据库底层存储的核心就是基于这些数据模型的。
InnoDB的索引模型
表都是根据主键顺序以索引的形式存放的,这种存储方式称为索引组织表。InnoDB使用了B+树的索引模型,所以数据都是存储在B+树中的。
索引类型分为主键索引和非主键索引:
- 主键索引:叶子节点存的是整行数据,也被称为聚簇索引
- 非主键索引:叶子节点内容是主键的值,也被称为二级索引
基于主键索引和普通索引的查询有什么区别?
- 如果语句是select *fromTwhere ID=500,即主键查询方式,则只需要搜索ID这棵B+树;
- 如果语句是select *fromTwhere k=5,即普通索引查询方式,则需要先搜索k索引树,得到ID
的值为500,再到ID索引树搜索一次。这个过程称为回表。
也就是说,基于非主键索引的查询需要多扫描一棵索引树,所以尽量使用主键查询。
为什么InnoDB选择B+树作为数据结构
B树
- B树在非叶子节点也要存储数据,** B 树的每个节点都包含数据(索引+记录)**,而用户的记录数据的大小很有可能远远超过了索引数据,这就需要花费更多的磁盘 I/O 操作次数来读到「有用的索引数据」。
- 而B+树叶子节点才会存放索引+记录,非叶子节点只会存放索引。非叶子节点的索引也会同时存在于子结点中。
相同磁盘I/O次数下,B+可以查到更多节点。而且B+树叶子采用的是双链表,适合于MySQL中常见的基于范围的顺序查找,而B树无法做到这一点。
二叉树
太高了。
hash
hash只适合等值查询,不适合范围查询。
索引维护
- 自增主键:是指自增列上定义的主键,在建表语句中一般是这么定义的: NOTNULL PRIMARY
KEY AUTO_INCREMENT。
插入新纪录的时候可以不指定ID的值,系统会获取当前ID最大值+1作为下一条记录的ID值,也就是说,自增主键的插入数据模式,符合递增插入的场景,每次插入一条新纪录都是追加操作,都不涉及到挪动其他记录也不会触发叶子节点的分裂。
有没有什么场合适合使用业务字段直接做主键呢?有的,比如有些业务场景需求是:
1、 只有一个索引
2、 该索引必须是唯一索引
由于没有其他索引,所以也就不用考虑其他索引的叶子节点大小问题。这个时候就要优先将这个索引设置为主键,尽量使用主键查询,避免每次查询需要搜索两棵树。
覆盖索引
如果执行的语句是select ID fromTwhere k between 3 and 5,这时只需要查ID的值,而ID的值已经在K索引树上了,因此可以直接提供查询结果,不需要回表。也就是说,在这个查询里面,索引k已经覆盖了我们的查询需求。
覆盖索引是指 SQL 中 query 的所有字段,在索引 B+Tree 的叶子节点上都能找得到的那些索引,从二级索引中查询得到记录,而不需要通过聚簇索引查询获得,可以避免回表的操作。
联合索引
建立在多列上的索引称为联合索引。
最左前缀
可以看到,索引项是按照索引定义里面出现的字段顺序排序的。
- 当你的逻辑需求是查到所有名字是“张三”的人时,可以快速定位到ID4,然后向后遍历得到所有
需要的结果。 - 如果你要查的是所有名字第一个字是“张”的人,你的SQL语句的条件是"where name like
‘张%’"。这时,你也能够用上这个索引,查找到第一个符合条件的记录是ID3,然后向后遍历,
直到不满足条件为止。
可以看到,不只是索引的全部定义,只要满足最左前缀,就可以利用索引来加速检索。这个最左
前缀可以是联合索引的最左N个字段,也可以是字符串索引的最左M个字符。
如何索引内字段顺序?
考虑索引的复用能力:第一原则是,如果通过调整顺序,可以少维护一个索引,那么这个顺序往往就是需要优先考虑采用的。
索引下推
MySQL 5.6 引入的索引下推优化(index condition pushdown), 可以在索引遍历过程中,对索引中包含的字段先做判断,直接过滤掉不满足条件的记录,减少回表次数。
- 对于这条语句
mysql> select * from tuser where name like '张%' and age=10 and ismale=1
没有下推
这个过程InnoDB并不会去看age的值,只是按顺序把“name第一个字是’张’”的记录一条条取出来回表。因此,需要回表4次。
有下推
InnoDB在(name,age)索引内部就判断了age是否等于10,对于不等于10的记录,直接判断并跳过。在这个例子中,只需要对ID4、ID5这两条记录回表取数据判断,就只需要回表2次。
什么时候需要索引?什么时候不需要?
需要索引
- 字段有唯一性限制的,比如商品编码;
- 经常用于 WHERE 查询条件的字段,这样能够提高整个表的查询速度,如果查询条件不是一个字段,可以建立联合索引。
- 经常用于 GROUP BY 和 ORDER BY 的字段,这样在查询的时候就不需要再去做一次排序了,因为我们都已经知道了建立索引之后在 B+Tree 中的记录都是排序好的。
不需要索引
- WHERE 条件,GROUP BY,ORDER BY 里用不到的字段,索引的价值是快速定位,如果起不到定位的字段通常是不需要创建索引的,因为索引是会占用物理空间的。
- 字段中存在大量重复数据,不需要创建索引,比如性别字段,只有男女,如果数据库表中,男女的记录分布均匀,那么无论搜索哪个值都可能得到一半的数据。在这些情况下,还不如不要索引,因为 MySQL 还有一个查询优化器,查询优化器发现某个值出现在表的数据行中的百分比很高的时候,它一般会忽略索引,进行全表扫描。
- 表数据太少的时候,不需要创建索引;
- 经常更新的字段不用创建索引,比如不要对电商项目的用户余额建立索引,因为索引字段频繁修改,由于要维护 B+Tree的有序性,那么就需要频繁的重建索引,这个过程是会影响数据库性能的。
索引优化
前缀索引优化
使用前缀索引是为了减小索引字段大小,可以增加一个索引页中存储的索引值,有效提高索引的查询速度。在一些大字符串的字段作为索引时,使用前缀索引可以帮助我们减小索引项的大小。
不过,前缀索引有一定的局限性,例如:
- order by 就无法使用前缀索引;
- 无法把前缀索引用作覆盖索引;
覆盖索引优化
可以建立一个联合索引,即「商品ID、名称、价格」作为一个联合索引。如果索引中存在这些数据,查询将不会再次检索主键索引,从而避免回表。所以,使用覆盖索引的好处就是,不需要查询出包含整行记录的所有信息,也就减少了大量的 I/O 操作。
主键索引自增
建表的时候,默认将主键索引设置为自增的。
索引最好设置为NOT NULL约束
- 索引列存在 NULL 就会导致优化器在做索引选择的时候更加复杂,更加难以优化,因为可为 NULL 的列会使索引、索引统计和值比较都更复杂,比如进行索引统计时,count 会省略值为NULL 的行。
- NULL 值是一个没意义的值,但是它会占用物理空间,所以会带来的存储空间的问题。
防止索引失效
避免写出索引失效的查询语句,否则这样的查询效率是很低的。
索引失效的情况
- 当我们使用左或者左右模糊匹配的时候,也就是 like %xx 或者 like %xx%这两种方式都会造成索引失效;
- 当我们在查询条件中对索引列做了计算、函数、类型转换操作,这些情况下都会造成索引失效;
- 联合索引要能正确使用需要遵循最左匹配原则,也就是按照最左优先的方式进行索引的匹配,否则就会导致索引失效。
- 在 WHERE 子句中,如果在 OR 前的条件列是索引列,而在 OR 后的条件列不是索引列,那么索引会失效。
相关文章:

《MySQL45讲》笔记—索引
索引 索引是为了提高数据查询效率,就像书的目录一样。如下图,索引和数据就是位于存储引擎中: 索引常见模型 哈希表 以键值对存储的数据结构。适用于只有等值查询的场景。 有序数组 在等值查询和范围查询场景中性能都特别优秀。但是有…...
Android usb host模式通信示例
当使用Android设备作为USB主机时,可以使用Android提供的USB API来进行USB通信。下面是一个简单的Android USB通信的示例。在这个示例中,我们将发送一条消息到连接的USB设备并从USB设备接收响应。 首先,在AndroidManifest.xml文件中添加以下权…...

开源Blazor UI组件库精选:让你的Blazor项目焕然一新!
今天给大家推荐一些开源、美观的Blazor UI组件库,这些优秀的开源框架和项目不仅能够帮助开发者们提高开发效率,还能够为他们的项目带来更加丰富的用户体验。 注:排名不分先后,都是十分优秀的开源框架和项目 Ant Design Blazor…...
MATLAB RANSAC圆柱体点云拟合 (28)
MATLAB RANSAC圆柱体点云拟合 (28) 一、算法介绍二、函数介绍三、算法实现四、效果展示一、算法介绍 RANSAC拟合方法,从原始点云中拟合具有特定形状的点云,这里对原始点云中大致呈圆柱的点云进行分割,圆柱的半径,以及朝向都是比较重要的定义圆柱的参数。下面是具体使用的…...
【AI】《动手学-深度学习-PyTorch版》笔记(七):自动微分
AI学习目录汇总 1、什么是自动微分 自动微分:automatic differentiation,深度学习框架通过自动计算导数,即自动微分,自动微分使系统能够随后反向传播梯度。 计算图:computational graph,根据设计好的模型,系统会构建一个计算图, 来跟踪计算是哪些数据通过哪些操作组合…...

vuejs源码阅读之代码生成器
代码生成器是模版编译的最后以后,它的作用是将AST转换成渲染函数中的内容,这个内容可以称为代码字符串。 代码字符串可以被包装在函数中执行,这个函数就是我们通常说的渲染函数。 渲染函数被执行之后,可以生成一份VNode…...

【MySQL】视图(十)
🚗MySQL学习第十站~ 🚩本文已收录至专栏:MySQL通关路 ❤️文末附全文思维导图,感谢各位点赞收藏支持~ 一.引入 视图(View)是一种虚拟存在的表。视图中的数据并不在数据库中实际存在,行和列数据…...

面试手写实现Promise.all
目录 前言常见面试手写系列Promise.resolve 简要回顾源码实现Promise.reject 简要回顾源码实现Promise.all 简要回顾源码实现Promise.allSettled 简要回顾源码实现Promise.race 简单回顾源码实现结尾 前言 (?﹏?)曾经真实发生在一个朋友身上的真实事件,面试官让…...

TCP网络通信编程之字符流
【案例1】 【题目描述】 【 注意事项】 (3条消息) 节点流和处理流 字符处理流BufferedReader、BufferedWriter,字节处理流-BufferedInputStream和BufferedOutputStream (代码均正确且可运行_Studying~的博客-CSDN博客 1。这里需要使用字符处理流,来将…...

佰维存储面向旗舰智能手机推出UFS3.1高速闪存
手机“性能铁三角”——SoC、运行内存、闪存决定了一款手机的用户体验和定位,其中存储器性能和容量对用户体验的影响越来越大。 针对旗舰智能手机,佰维推出了UFS3.1高速闪存,写入速度最高可达1800MB/s,是上一代通用闪存存储的4倍以…...
降龙十八掌
目录 大数据: 1 HIVE: 1.1 HIVE QL 1.1.1 创建表 1.1.2 更新表 1.1.3 常用语句 1.2 hive参数配置 大数据: 1 HIVE: 1.1 HIVE QL DDL中常用的命令有:create,drop,alter,trunc…...

【项目设计】MySQL 连接池的设计
目录 👉关键技术点👈👉项目背景👈👉连接池功能点介绍👈👉MySQL Server 参数介绍👈👉功能实现设计👈👉开发平台选型👈👉MyS…...
Ubuntu系统adb开发调试问题记录
Ubuntu系统adb开发调试问题记录 一、adb devices no permissions二、自定义adb server端口三、动态库目录四、USB抓包 一、adb devices no permissions lsusb -t 设备树直观地查看设备的Bus ID和Device Num,lsusb找到对应的PID和VID编辑udev规则 sudo vim /etc/ud…...
【宏定义】——检验条件是否成立,并返回指定的值
文章目录 功能说明实现示例解析扩展 功能说明 宏检验条件是否成立,并返回指定的值 #define TU_VERIFY(...) _GET_3RD_ARG(__VA_ARGS__, TU_VERIFY_2ARGS, TU_VERIFY_1ARGS, UNUSED)(__VA_ARGS__)TU_VERIFY(1) 检验为真,啥也不干TU_VERIFY(0) 校验为假&…...
UE5引擎源码小记 —反射信息注册过程
序 最近看了看反射相关的知识,用不说一点人话的方式来说,反射是程序在运行中能够动态获取修改或调用自身属性的东西。 一开始我是觉得反射用处好像不大,后续查了下一些反射的使用环境,发现我格局小了,我觉得用处不大的…...

Redis缓存预热
说明:项目中使用到Redis,正常情况,我们会在用户首次查询数据的同时把该数据按照一定命名规则,存储到Redis中,称为冷启动(如下图),这种方式在一些情况下可能会给数据库带来较大的压力…...

Android 耗时分析(adb shell/Studio CPU Profiler/插桩Trace API)
1.adb logcat 查看冷启动时间和Activity显示时间: 过滤Displayed关键字,可看到Activity的显示时间 那上面display后面的是时间是指包含哪些过程的时间呢? 模拟在Application中沉睡1秒操作,冷启动情况下: 从上可知&…...
保护隐私与安全的防关联、多开浏览器
随着互联网的不断发展,我们越来越离不开浏览器这个工具,它为我们提供了便捷的网络浏览体验。然而,随着我们在互联网上的活动越来越多,我们的个人信息和隐私也日益暴露在网络风险之下。在这种背景下,为了保护个人隐私和…...

CloudStudio搭建Next框架博客_抛开电脑性能在云端编程(沉浸式体验)
文章目录 ⭐前言⭐进入cloud studio工作区指引💖 注册coding账号💖 选择cloud studio💖 cloud studio选择next.js💖 安装react的ui框架(tDesign)💖 安装axios💖 代理请求跨域&#x…...
【FPGA IP系列】FIFO深度计算详解
FIFO(First In First Out)是一种先进先出的存储结构,经常被用来在FPGA设计中进行数据缓存或者匹配传输速率。 FIFO的一个关键参数是其深度,也就是FIFO能够存储的数据条数,深度设计的合理,可以防止数据溢出,也可以节省…...
JavaScript中语句和表达式
在JavaScript编程中,Statements和Expressions都是代码的构建块,但它们有不同的特点和用途。 ● Statements(语句)是执行某些操作的完整命令;每个语句通常以分号结束。例如,if语句、for语句、switch语句、函…...
打卡力扣题目十
#左耳听风 ARST 打卡活动重启# 目录 一、题目 二、解决方法一 三、解决方法二 关于 ARTS 的释义 —— 每周完成一个 ARTS: ● Algorithm: 每周至少做一个 LeetCode 的算法题 ● Review: 阅读并点评至少一篇英文技术文章 ● Tips: 学习至少一个技术技巧 ● Shar…...
UniApp实现API接口封装与请求方法的设计与开发方法
UniApp实现API接口封装与请求方法的设计与开发方法 导语:UniApp是一个基于Vue.js的跨平台开发框架,可以同时开发iOS、Android和H5应用。在UniApp中,实现API接口封装与请求方法的设计与开发是一个十分重要的部分。本文将介绍如何使用UniApp实…...

利用小波分解信号,再重构
function [ output_args ] example4_5( input_args ) %EXAMPLE4_5 Summary of this function goes here % Detailed explanation goes here clc; clear; load leleccum; s leleccum(1:3920); % 进行3层小波分解,小波基函数为db2 [c,l] wavedec(s,3,db2); %进行…...

QT数据库编程
ui界面 mainwindow.cpp #include "mainwindow.h" #include "ui_mainwindow.h" #include <QButtonGroup> #include <QFileDialog> #include <QMessageBox> MainWindow::MainWindow(QWidget* parent): QMainWindow(parent), ui(new Ui::M…...

基于stm32单片机的直流电机速度控制——LZW
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 一、实验目的二、实验方法三、实验设计1.实验器材2.电路连接3.软件设计(1)实验变量(2)功能模块a)电机接收信号…...
实际项目中使用mockjs模拟数据
项目中的痛点 自己模拟的数据对代码的侵入程度太高,接口完成后要删掉对应的代码,导致接口开发完后端同事开发完,前端自己得加班;接口联调的时间有可能会延期,接口完成的质量参差不齐;对于数据量过大的模拟…...

【家庭公网IPv6】
家庭公网IPv6 这里有两个网站: 1、 IPV6版、多地Tcping、禁Ping版、tcp协议、tcping、端口延迟测试,在本机搭建好服务器后,可以用这个测试外网是否可以访问本机; 2、 IP查询ipw.cn,这个可以查询本机的网络是否IPv6访问…...

【iOS】Frame与Bounds的区别详解
iOS的坐标系 iOS特有的坐标是,是在iOS坐标系的左上角为坐标原点,往右为X正方向,向下为Y正方向。 bounds和frame都是属于CGRect类型的结构体,系统的定义如下,包含一个CGPoint(起点)和一个CGSiz…...

SpringBoot百货超市商城系统 附带详细运行指导视频
文章目录 一、项目演示二、项目介绍三、运行截图四、主要代码 一、项目演示 项目演示地址: 视频地址 二、项目介绍 项目描述:这是一个基于SpringBoot框架开发的百货超市系统。首先,这是一个很适合SpringBoot初学者学习的项目,代…...