数据库索引b树 b+树_b树索引

数据库索引b树 b+树_b树索引一、什么是索引 在进行索引之前,我们先提前复习一下数据库的结构 数据库索引,是数据库管理系统中一个排序的数据结构,以协助快速查询、更新数据库表中数据。就像我们以前用的新华字典的目录一样,能帮助我们快…

	数据库,从B+树讲到索引优化,听不明白你找我[数据库教程]

一、什么是索引

在进行索引之前,我们先提前复习一下数据库的结构

数据库,从B+树讲到索引优化,听不明白你找我

 

数据库索引,是数据库管理系统中一个排序的数据结构,以协助快速查询、更新数据库表中数据。就像我们以前用的新华字典的目录一样,能帮助我们快速查询到某一个字。

具体的来看一下

数据库,从B+树讲到索引优化,听不明白你找我

 

二、索引的分类

分类角度索引名称数据结构B+树,Hash索引,R-Tree等存储层面聚簇索引,非聚簇索引逻辑层面主键索引,普通索引,复合索引,唯一索引,空间索引等

这样说有点不明白?图解奉上

数据库,从B+树讲到索引优化,听不明白你找我

 

还不明白,没关系,这么看图确实有点抽象,那我们就来看一下实例

三、索引实例分析(以InnoDB为例)

3.1 InnoDB下索引的结构

InnoDB下,表都是根据主键顺序以索引的形式存放的,这种数据存储方式也被称为聚簇索引,“聚簇”就是表示数据行和相邻的键值紧凑的存储在一起,也就是数据行实际上是存储在索引的叶子页中。我们创建一张表来实际说明下InnoDB下的索引结构,建表语句如下:

create table person(
id int primary key,
age int not null
index (age)engine=InnoDB;

代码100分

然后我们插入五条数据分别为(1,15),(2,17),(6,20),(10,18),(19,21),索引的树结构如下:

数据库,从B+树讲到索引优化,听不明白你找我

 

上图中展示了两部分内容,第一个图为聚簇索引(主键索引)的内容,可以看到,数据按照Id的大小排序,对应的索引会包含该索引的整行数据。

第二个图展示了用age做索引的索引结构图,也就是非聚簇索引(非主键索引),可以看到索引以年龄排序,但是和主键索引不同的是,年龄索引对应的却是Id,所以我们可以知道非主键索引记录的内容就是主键索引的值。

这里可能有同学会有疑问,如果我建表的时候没有指定主键的话,索引结构又是如何的呢?其实在InnoDB中,如果没有定义主键,那么他会选择一个唯一的非空索引代替。如果没有这样的索引,那么他会隐式的定义一个主键来作为聚簇索引。所以无论你是否设置主键,InnoDB还是会帮你满足以上图的形式来索引数据。接下来我们分析下索引查询的流程。

3.2 索引查询分析

假设我们执行一条查询语句 select * from person where ID = 6 ,因为直接使用的是主键ID查询,所以就会用主键索引,由于主键索引直接关联了整行所有数据,所以,引擎只要执行一次就能查询出结果。

如果执行的sql语句是非主键索引

select * from person where age = 18

上述语句会走age的普通索引,索引先根据age搜索等于18的索引记录,找到ID=10的记录,然后再到主键索引搜索一次,然后拿出需要查询的数据。

从普通索引查出主键索引,然后查询出数据的过程叫做回表。由于回表需要多执行一次查询,这也是为什么主键索引要比普通索引要快的原因,所以,我们要尽量使用主键查询。

3.3 覆盖索引

我们通常创建索引的依据都是根据查询的where条件,但是这只是我们通常的做法,我们根据上面的分析可以知道,如果要想查询效率高,第一,使用主键索引,第二,避免回表,也就是尽可能的在索引中就能获取想要的数据。如果一个索引包含了需要查询的字段,那么我们就叫做“覆盖索引”。

那么如何建立一个覆盖索引呢?答案是通过联合索引来实现,通过联合索引的字段来覆盖要查询的字段,从而达到索引覆盖的效果。

我们把上面的建表语句改造下,来分析下如何实现覆盖索引。

代码100分 CREATE TABLE `person` (
`id` int(11) NOT NULL,
`age` int(11) DEFAULT NULL,
`name` varchar(20) DEFAULT NULL,
`sex` varchar(1) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `name_age` (`name`,`age`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

上面我创建了一个name和age的联合索引,索引结构图表示如下:

数据库,从B+树讲到索引优化,听不明白你找我

 

我们根据图可以知道,联合索引是和创建索引字段顺序有关的,上面这个例子就是先以name排序,然后name相同再以age为标准排序。那么我们建表后该如何达到覆盖索引的效果呢?相信有些同学已经知道了怎么写sql可以达到覆盖索引效果,sql如下:

select name,age from person where name = “Barry”

因为我们需要查询的字段name和age,都在索引中可以直接查询到了,所以不需要查找到主键ID,然后再回表了。

看到这里,肯定有同学会说,既然这样的话,我把所有需要查询的字段组合都建上联合索引不就行了吗?答案是:不行。因为索引也是需要消耗空间的,而且维护索引也是需要成本的,这一点我会在后面的优缺点中提到。那么有没有别的方式可以尽可能的实现不回表的效果呢?这里我们就要引入MySql的最左前缀原则了。

什么叫最左前缀原则呢?就是在索引的匹配中,可以以索引的最左N个字段,也可以是字符串索引的最左N个字符。比如在上图中,要查询以A开头的名字,查询语句就是

select name from person where name like ‘A%‘

这个时候就可以满足最左前缀规则来使用索引查询了,这里就会依赖索引查询到第一个首字母是A的名字,然后向后遍历,直到不满足条件为止。

那么最左N个字段是什么意思呢?意思就是索引(name,age),可以直接利用 name来当做单独索引使用,可以只使用联合索引的部分字段,但是必须是顺序一致,比如索引(a,b,c),如果要想使用最左前缀规则,可以使用索引a,ab。

我们也可以利用该规则来少维护一个或多个索引,比如我们需要 a,ab,abc的查询,那就只需要(a,b,c)联合索引就满足要求了。

3.4 索引下推

在MySql 5.6版本中引入了一个新特性,叫做“索引条件推送(index condition pushdown)”,这也称为索引下推。那么索引下推是这个什么东东呢?其实从“索引条件推送”这个名字就可以表明,这个特性是可以在索引中的字段进行条件判断,然后过滤不满足条件的记录,减少回表的次数。

比如以上图中的数据为准,sql如下:

select * from person where name like ‘A%‘ and age =19;

那么如果没有索引下推的情况下,首先会根据索引查询出名字以A开头的所有记录,然后查询出ID,然后回表去查询对应的ID记录,最后再判断age=19,返回满足条件的语句。因为满足A开头的记录有2条,所以这种情况下,会回表2次。

在索引下推情况下,InnoDB会在索引内部直接判断age=19是否满足条件,过滤掉不满足条件的记录,所以只返回了一条,也就是只需要回表一次。从而提高了性能。

3.5 索引的优点与缺点

说了这么多关于索引的内容,我们来谈谈索引的优缺点。

优点:

  • 减少服务器需要扫描的数据量
  • 索引可以帮助服务器避免排序和临时表
  • 索引可以将随机IO变为顺序IO

缺点

  • 索引会占用额外的存储空间
  • 索引的维护需要一定的成本,插入数据后需要保证原来的索引有序,所以也会影响一定的数据库性能。

所以在优化方面,索引优化算是数据库优化中很重要的一个环节,这里因为篇幅原因我就不一一详解了,相关的内容我已经完整整理成思维导图,每一个方面整理的都很详细

数据库,从B+树讲到索引优化,听不明白你找我

 

需要这份优化思维导图以及上面的知识图的老铁,添加小助手:msbxq2020免费获取,同步的还有相关的视频讲解以及学习文档,还不快点行动

关注公众号:Java架构师联盟,每日更新技术好文

部分资料已经上传到我的git仓库中:有需要的可以下载

数据库,从B+树讲到索引优化,听不明白你找我

原文地址:https://www.cnblogs.com/bwscode/p/13368526.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/7141.html

(0)
上一篇 2023-03-26 13:30
下一篇 2023-03-26

相关推荐

  • Python按钮:点击即实现快速功能实现

    Python按钮:点击即实现快速功能实现Python是一种流行的编程语言,其简单易用的语法和广泛的应用使其成为学习编程的理想选择。在本文中,我们将介绍如何使用Python按钮点击即实现快速功能实现。无论您是想编写一个小的桌面应用程序、网络爬虫或任何其他应用程序,Python都可以帮助您实现。

    2024-02-14
    41
  • mysql默认的事务隔离级别能达到什么效果_mysql常用事务隔离级别

    mysql默认的事务隔离级别能达到什么效果_mysql常用事务隔离级别只需要五分钟,你就可以了解到事务及其ACID特性,并且真正地理解MySQL事务隔离级别:未提交读、提交读、可重复读、可串行化,还有什么是脏读、不可重复读、幻读。

    2023-01-27
    108
  • MySQL:分库分表与分区的区别和思考

    MySQL:分库分表与分区的区别和思考一.分分合合 说过很多次,不要拘泥于某一个技术的一点,技术是相通的。重要的是编程思想,思想是最重要的。当数据量大的时候,需要具有分的思想去细化粒度。当数据量太碎片的时候,需要具有合的思想来粗化粒度。…

    2023-03-29
    108
  • 优化简历表现:利用Python xyz公式打造独特履历

    优化简历表现:利用Python xyz公式打造独特履历当我们投递简历的时候,经常会发现简历和其他人的相似度较高,这时候就需要一些独特的方法去吸引招聘人员的眼球,提高简历通过率。本文将介绍一种利用Python xyz公式打造独特履历的方法,通过代码的方式帮助大家生成独特的简历,吸引招聘人员的关注。

    2024-01-19
    55
  • Docker安装Mysql5.7[通俗易懂]

    Docker安装Mysql5.7[通俗易懂]Docker安装 系统版本:CentOS Linux release 7.5.1804 (Core) 如果之前有装过docker可以先卸载旧版本再安装,没有则跳过。 yum remove docker

    2023-02-03
    90
  • 【mysql】新手必备 centos7 安装mysql8[通俗易懂]

    【mysql】新手必备 centos7 安装mysql8[通俗易懂]@[toc] 前言 在CentOS中默认的数据库是mariadb, 所以安装mysql比以前稍微有了点难度,尤其对于新手来说,看着文档就是做不出来。很无奈,今天我特地整理了在centos7中安装my…

    2023-03-24
    96
  • mongodb聚合机制_mongodb集群模式

    mongodb聚合机制_mongodb集群模式$out 将聚合管道中的文档,写入到一个新的集合 output 中。如果 output 已存在且有数据,则原有的数据会被清空 db.transactions.aggregate([ { $group…

    2023-02-14
    102
  • sql创建数据库语句_数据库建表语句

    sql创建数据库语句_数据库建表语句本文介绍如何使用 SQL INSERT 语句将数据插入到表中,如何用 INSERT SELECT 从其他表中导入行,如何用 SELECT INTO 将行导出到一个新表。 一、数据插入 毫无疑问,SEL

    2023-05-18
    105

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注