(四)Mysql之索引介绍
索引数据结构的选择:Hash表、二叉树、平衡二叉树、(红黑树近似于平衡二叉树)、B树、B+树
1)Hash表:Java的HashMap、TreeMap就是Hash表结构,以键值对存储,时间复杂度是O(1),但是不支持范围的快速查询,范围查询时得需要全表扫描。
2)二叉查找树:二叉树的特点是每个节点最多有两个分叉,左子树与右子树数据顺序左小右大。查找的效率与树的高度相关。
不是所有的列都适合用二叉查找树,比如递增的id,用二叉查找树时会退化为链表。查找时相当于全表扫描
3)平衡二叉查找树:采用二分法思想,最主要的特征是树的左右两个子树的层级最多相差1. 在插入删除数据的时候通过左旋与右旋操作保持二叉查找树的平衡
不会出现左子树很高,右子树很低的情况。平衡二叉查找树也具备二叉查找树的特点,查询的时间复杂度是O(log2n)
缺点:
1 时间复杂度与树的高度相关,树有多高,就需要检索多少次,每个节点的读取都对应一次IO操作。
2 不支持范围查找,范围查询需要从根节点多次遍历,此时效率不高。
4)B树:改造二叉树
Mysql的数据是存储在磁盘文件中的,查询处理数据时,需要先把磁盘中的数据加载到内存,磁盘的IO操作非常耗时,所以我们要尽量减少磁盘的IO操作,也就是尽量减少树的高度。为了最大化利用一次IO空间,最简单的做法,每个节点存储多个元素,这样将二叉树改造成了多叉树,通过增加树的叉树,将树的高度从高瘦变为矮胖。这样的一种数据结构称为B树,B树是一种多叉平衡查找树,主要有如下特点。
1 B树的每个节点存储了多个元素,每个节点内有多个分叉
2 节点中的元素既包含键值也包含了数据,也就是在所有的节点都存储数据
3 父节点当中的元素不会出现在子节点中
4 所有的叶子节点都位于同一层,具有同样的深度,叶节点之间没有指针连接
5)B+树:改造B树
B+树与B树最主要的区别就是非叶子节点是否存储数据。
B+树:只有叶子节点才会存储数据,非叶子节点只存储键值。叶子节点之间使用双向指针连接,最底层的叶子节点形成了一个双向有序的链表。
这样非叶子节点不存储数据,就可以存储更多的键值,将树的高度变得更低,更好地减少了磁盘IO的次数。
MyIsam索引实现:
MyISAM的数据文件和索引文件是分开存储的。MyISAM使用B+树构建索引树时,叶子节点中存储的键值为索引列的值,数据为索引所在行的磁盘地址。
在 MyISAM 中,辅助索引和主键索引的结构是一样的,没有任何区别,叶子节点的数据存储的都是行记录的磁盘地址。只是主键索引的键值是唯一的,而辅助索引的键值可以重复。
查询数据时,由于辅助索引的键值不唯一,可能存在多个拥有相同的记录,所以即使是等值查询,也需要按照范围查询的方式在辅助索引树中检索数据。
Innodb索引实现:
每个Innodb表都有一个聚簇索引,聚簇索引使用B+树构建,叶子节点存储的是整行记录,一般情况下聚簇索引等同于主键索引,当一个表没有创建主键索引时,Innodb会自动创建一个ROWID字段来构建聚簇索引。创建规则如下:
1 表中定义主键primary key,Innodb会将主键索引引用作聚簇索引
2 如果表没有定义主键,Innodb会选择第一个不为NULL的唯一索引作为聚簇索引
3 如果以上都没有,会使用6字节长整型的隐式字段Rowid构建聚簇索引。该Rowid字段会在插入新行时自动递增。
除聚簇索引之外的索引都成为辅助索引。在Innodb中,辅助索引中的叶子节点存储的数据是该行的主键值,在检索时,Innodb使用此主键值在聚簇索引中搜索行记录(回表)。
组合索引:
组合索引的最左匹配原则:使用组合索引查询时,mysql会一直向右匹配直至遇到范围查询(>、< 、betweek、like)就停止匹配。
索引使用口诀:
全值匹配我最爱,最左前缀要遵守
带头大哥不能死,中间兄弟不能断
索引列上不计算,范围之后全失效
like百分写最右,覆盖索引不写*
不等控制还有or,索引失效要少用
组合索引创建原则:
1 频繁出现在where条件中的列,建议创建组合索引
2 频繁出现在order by 和 group by语句中的列,建议按照顺序去创建组合索引 order by a,b 需要组合索引列顺序(a,b),相反如果是(b,a)
是用不到索引的。
3 常出现在select语句中的列,也建议创建组合索引
索引优化建议
1. 表记录很少不需创建索引 (索引是要有存储的开销).
2. 一个表的索引个数不能过多。
(1)空间:浪费空间。每个索引都是一个索引树,占据大量的磁盘空间。
(2)时间:更新(插入/Delete/Update)变慢。需要更新所有的索引树。太多的索引也会增加优化器的选择时间。
所以索引虽然能够提高查询效率,索引并不是越多越好,应该只为需要的列创建索引。
3. 频繁更新的字段不建议作为索引。
频繁更新的字段引发频繁的页分裂和页合并,性能消耗比较高。
4. 区分度低的字段,不建议建索引。(仅供参考)
比如性别,男,女;比如状态。区分度太低时,会导致扫描行数过多,再加上回表查询的消耗。如果使用索引,比全表扫描的性能还要差。这些字段一般会用在组合索引中。姓名,手机号就非常适合建索引。
5. 在InnoDB存储引擎中,主键索引建议使用自增的长整型,避免使用很长的字段。
主键索引树一个页节点是16K,主键字段越长,一个页可存储的数据量就会越少,比较臃肿,查询时尤其是区间查询时磁盘IO次数会增多。辅助索引树上叶子节点存储的数据是主键值,主键值越长,一个页可存储的数据量就会越少,查询时磁盘IO次数会增多,查询效率会降低。
6. 不建议用无序的值作为索引。例如身份证、UUID
更新数据时会发生频繁的页分裂,页内数据不紧凑,浪费磁盘空间。
7. 尽量创建组合索引,而不是单列索引。
优点
(1)1个组合索引等同于多个索引效果,节省空间。
(2)可以使用覆盖索引
创建原则:组合索引应该把把频繁的列,区分度高的值放在前面。频繁使用代表索引的利用率高,区分度高代表筛选粒度大,可以尽量缩小筛选范围。
(四)Mysql之索引介绍的更多相关文章
- MySQL InnoDB索引介绍以及在线添加索引实例分析
引言:MySQL之所以能成为经典,不是没有道理的,B+树足矣! 一.索引概念 InnoDB引擎支持三种常见的索引:B+树索引,全文索引和(自适应)哈希索引.B+树索引是传统意义上的索引,构造类似二叉树 ...
- MySQL数据库索引介绍
一.什么是索引 索引是mysql数据库中的一种数据结构,就是一种数据的组织方式,这种数据结构又称为key 表中的一行行数据按照索引规定的结构组织成了一种树型结构,该树叫B+树 二.为何要用索引 优化查 ...
- Mysql常见索引介绍
索引是一种特殊的文件,包含了对数据表中所有记录的引用指针.InnoDB引擎的数据库,其上的索引是表空间的一个组成部分. (1).索引的优缺点 优点:加快搜索速度,减少查询时间 缺点:索引是以文件的形式 ...
- MySQL高级学习笔记(四):索引优化分析
文章目录 性能下降 SQL慢 执行时间长 等待时间长 查询语句写的烂 查询数据过多 关联了太多的表,太多join 没有利用到索引 单值 复合 服务器调优及各个参数设置(缓冲.线程数等)(不重要DBA的 ...
- MySQL单列索引和组合索引的区别介绍
MySQL单列索引和组合索引的区别介绍 作者:佚名出处:IT专家网2010-11-22 13:05 MySQL单列索引是我们使用MySQL数据库中经常会见到的,MySQL单列索引和组合索引的区别可能有 ...
- MySQL索引介绍
引言 今天Qi号与大家分享什么是索引.其实索引:索引就相当于书的目录 索引介绍 用官方的话说就是 索引是为了加速对表中数据行的检索而创建的一种分散的存储结构.索引是针对表而建立的,它是由数据页面以外的 ...
- mysql性能优化-慢查询分析、优化索引和配置 MySQL索引介绍
MySQL索引介绍 聚集索引(Clustered Index)----叶子节点存放整行记录辅助索引(Secondary Index)----叶子节点存放row identifier-------Inn ...
- mysql数据库中的索引介绍与优化(转)
一.什么是索引? 索引用来快速地寻找那些具有特定值的记录,所有MySQL索引都以B-树的形式保存.如果没有索引,执行查询时MySQL必须从第一个记录开始扫描整个表的所有记录,直至找到符合要求的记录.表 ...
- MySQL数据库索引:索引介绍和使用原则
本篇目录: 一.数据页与索引页 二.聚簇索引与非聚簇索引 三.唯一索引 四.索引的创建 五.索引的使用规则 六.数据库索引失效情况 本篇正文: 一.数据页与索引页 数据库的表存储分为数据页存储和索引页 ...
- MySQL索引介绍和实战
索引是什么 MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构. 可以得到索引的本质:索引是数据结构,索引的目的是提高查询效率,可以类比英语新华字典,根据目录定位词 ...
随机推荐
- VSCode解决Python中空格和制表符混用报错
Python对缩进的要求非常严格,缩进控制不正确可能会造成代码执行不正确甚至报错. 遇到报错"TabError: inconsistent use of tabs and spaces in ...
- Linux命令第三部分
一.命令 1.mv命令 ·不更改文件路径 改名 ·更改文件路径 剪切 mv [选项] 源文件或目录 目标文件或目录 2.which 查找命令.文件存放目录 搜索范围由环境变量PATH决定 3. ...
- vscode下无法使用fresh的问题
使用了go get github.com/pilu/fresh ,需要 go install github.com/pilu/fresh. 在带用go.mod的版本中,go get只是下载代码和帮助修 ...
- 5、枚举Enum
枚举类会隐式的继承Enum类,无法再继承其它类(单继承机制) 一.无实参枚举类型: 1.定义: /** * 1.无实参枚举类型 */ public enum NoParamTypeEnums { SP ...
- 【转载】SQL SERVER 表变量与临时表的优缺点
什么情况下使用表变量?什么情况下使用临时表? -- 表变量: DECLARE @tb table(id int identity(1,1), name varchar(100)) INSERT @tb ...
- js获取天气插件
SDK介绍 根据指定入参,传入三个 select 的 id值 及 回调函数,每次选项变更都会拿到对应地区最新天气数据. 必须是三个 Select 标签 有记住选项功能,避免重复相关逻辑. 1.依赖源码 ...
- 二十三、图的遍历(BFS和DFS)
一.概念 图的遍历(Traversing Graph)从某一顶点出发,访问图中所有顶点,且使每一顶点仅被访问一次.与树的遍历不同的是,图的遍历需要处理两种特殊情况:一是从某一顶点出发进行遍历时,可 ...
- 迁移学习(DIFEX)《Domain-invariant Feature Exploration for Domain Generalization》
论文信息 论文标题:Domain-invariant Feature Exploration for Domain Generalization论文作者:Wang Lu, Jindong Wang, ...
- 如何使用MASA.Blazor
MASA.Blazor 是什么? 基于Material Design设计和BlazorComponent的交互能力提供标准的基础组件库.提供如布局.弹框标准.Loading.全局异常处理等标准场景的预 ...
- Java线程池中的execute和submit
一.概述 execute和submit都是线程池中执行任务的方法. execute是Executor接口中的方法 public interface Executor { void execute(Ru ...