MySQL索引树(B树和B+树)使用及说明

 更新时间:2026年10月26日 09:36:34   作者:羊驼有点累  
还在纠结B树和B+树怎么选?本文用大白话讲清B树的阶、插入删除规则,对比B+树在数据库索引中的优势,还盘点了Hash、全文、R树等常见索引类型,帮你搞懂为什么范围查询偏爱B+树

BTree

一个多路平衡二叉树,出自于AVL树,但是AVL树的高度太高,查询效率太低

注意:

m也就是B树的阶,至于B树的阶如何确定,那么就需要看B树子节点允许存在的最大子孩子(子树)的数量,允许节点存在m-1个关键字。

每个节点最多只有m个子节点。

每个非叶子节点(除了根)具有至少⌈ m/2⌉子节点。

如果根不是叶节点,则根至少有两个子节点。

具有k个子节点的非叶节点包含k -1个键。

所有叶子都出现在同一水平,没有任何信息(高度一致)。

B树的阶

B树中,一个节点的子节点数目最大值

B树的根

也就是最顶端那一个节点,如果根节点并非树中唯一节点,那必须有两个子节点,要不然就成为了单支节点

B树的内部节点

就是除根节点和叶子节点之外的所有节点

B树的叶子节点

B树的最后一层节点,没有子节点,也没有指向子节点的指针

B树的插入

B树插入m阶B树时,如果该节点的元素个数小于m则直接插入,

如果节点的个数大于或者等于m,则会先分裂,取节点的中间元素插入到父节点中(偶数,取中间两个数的随机一个),然后将元素插入

最坏的情况就是一直分裂到根节点,树的高度加一

B树的删除操作

如果B树中的某个节点的元素数目小于(m/2)-1,m/2向上取整,这时需要看相邻节点的数量是否满足(m/2)-1,如果满足,直接向父节点借一个元素,如果不满足,则两个节点合并

磁盘的IO

磁盘的IO读写的花费时间分为三个部分寻道时间+旋转延迟和传输时间,寻道指的是磁臂移动到指定磁道所花费的时间,旋转延迟是指磁盘的转速,比如磁盘转速为7200r,那么每分钟就是7200r,每秒就是120r,旋转延迟也就是转一圈就是4.17ms,传输时间是指将数据读出或者写入的时间。

在数十亿条并发指令下,计算机资源尤为昂贵,所以,提出了内缓存区,在数据读取时,也会将相邻数据读到内缓存区中,每次IO读写都是一个数据块,在数据库中称为一页,页的大小和操作系统有关,有的4K,有的16K

B+树

有m个子树的中间节点包含有m个元素(B树中是k-1个元素),每个元素不保存数据,只用来存取索引;

所有的叶子结点中包含了全部关键字的信息,及指向含有这些关键字记录的指针,且叶子结点本身依关键字的大小自小而大的顺序链接。 (而B 树的叶子节点并没有包括全部需要查找的信息);

所有的非终端结点可以看成是索引部分,结点中仅含有其子树根结点中最大(或最小)关键字。 (而B 树的非终节点也包含需要查找的有效信息);

索引结构类型

按数据结构分类

B+tree索引、Hash索引、Full-text索引、Rtree索引。

BTree索引、Hash索引、full-text索引、R-Tree索引

BTree索引在上边已经介绍

hash索引

也就是采用hash表的结构,k-v键值对的形式,所以对于数据的检索效率是非常高的,

但是hash索引无法支持范围查询,应为hash内部的key是无序的,没有办法利用,那么hash索引自然也不支持order by

hash索引无法支持联合索引的最左匹配原则,因为hash是将多个索引键键合并在一起计算hash值,不会针对单个索引键做计算,自然不支持联合索引,更不用说最左匹配

但是hash在做等值查询时的效率非常高

FullText索引

MySQL主要要来做搜索引擎,且只有字段的数据类型为 char、varchar、text 及其系列才可以建全文索引

select * from answer where match(字段) against("表名")

为了更好的所有效果,需要在mysql的配置文件做更改,也就是my.ini

// MyISAM
ft_min_word_len = 4; 默认值
ft_max_word_len = 84; 默认值
// InnoDB
innodb_ft_min_token_size = 3; 默认值
innodb_ft_max_token_size = 84; 默认值
//ngram解析器令牌长度----即against()中字符串切分的最小字符长度
ngram_token_size = 2~10 ; 默认值
一般设定:(以下例子均是假定设置如下)
在 [mysqld]的下面追加:
innodb_ft_min_token_size = 2
ft_min_word_len = 2
ngram_token_size = 2

修改后重启mysql服务,打开任务管理器,找到mysql服务,直接右键重启

使用如下语法,在命令行查看变量

show variables like "%ft%"
show variables like "%ngram%"

使用语法

  • 【+】----------必须包含此字符串
  • 【-】----------必须不包含此字符串
  • 【“ ”】--------双引号内作为整体不能拆词
  • 【> 】--------提高该词的相关性,查询的结果靠前
  • 【< 】--------降低该词的相关性,查询的结果靠后
  • 【*】---------通配符,只能接在词后面
SELECT * FROM user WHERE MATCH(userName) AGAINST (‘+“张” & +“三” ' IN BOOLEAN MODE);

RTree

空间索引,它将空间对象按范围划分,每个结点都对应一个区域和一个磁盘页,非叶结点的磁盘页中存储其所有子结点的区域范围,所以更适合做范围查询

但它仅支持geometry数据类型,支持该类型的存储引擎只有myisam、bdb、innodb、ndb几种。

索引又分为聚集索引和非聚集索引

按物理存储分类

聚集索引、非聚集索引(也叫二级索引、辅助索引)。

按字段特性分类

主键索引(PRIMARY KEY)、唯一索引(UNIQUE)、普通索引(INDEX)、组合索引、全文索引(FULLTEXT)。

按字段个数分类

单列索引、联合索引(组合索引)

为什么B+树更适合用来做数据库索引树?

首先,B+树内部节点并没有存储指向关键字具体信息的指针,所以B+树的内部节点比B树的内部节点更小,在一页或块中,所能容纳更多的关键字信息

非终节点并不是最终指向文件内容的节点,而是指向叶子节点关键字信息的指针,所以任何关键字的查找都是需要从根节点到叶子节点的查询,所以查询效率基本相同

B+树更适合做范围查询,因为B+树中的关键字信息都是存放在叶子节点中,所以只需要遍历叶子节点就可以查找到所有元素(B树用的是中序遍历,B+树是链表遍历)

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • MySQL的两种分页方式之Offset/Limit分页和游标分页详解

    MySQL的两种分页方式之Offset/Limit分页和游标分页详解

    这篇文章主要对比了MySQL的Offset/Limit分页与游标分页,指出前者简单但存在数据漂移和性能缺陷,后者通过游标避免这些问题且更高效,建议根据业务场景选择分页方式,深度分页或动态数据宜用游标分页,而延迟联结可优化Offset/Limit性能,需要的朋友可以参考下
    2025-09-09
  • MySQL修改root密码的多种方法(推荐)

    MySQL修改root密码的多种方法(推荐)

    本文给大家分享了三种方法来解决mysql修改root密码的方法,非常不错,具有参考借鉴价值,需要的朋友参考下吧
    2017-03-03
  • MySQL数据表基本操作实例详解

    MySQL数据表基本操作实例详解

    这篇文章主要介绍了MySQL数据表基本操作,结合实例形式较为详细的分析了MySQL针对数据表的基本创建、表结构查看、修改、删除等相关操作技巧,需要的朋友可以参考下
    2018-06-06
  • 拥有5星评级数据库表结构 如何才能更高效的使用?

    拥有5星评级数据库表结构 如何才能更高效的使用?

    本篇文章介绍了,拥有5星评级数据库表结构 如何才能更高效的使用的方法。需要的朋友参考下
    2013-04-04
  • Linux系统下MySQL的初始化和配置指南

    Linux系统下MySQL的初始化和配置指南

    当MySQL的系统库(mysql系统库)发生故障或需要新加一个mysql实例时,需要初始化mysql数据库,这篇文章主要给大家介绍了关于Linux系统下MySQL的初始化和配置指南的相关资料,需要的朋友可以参考下
    2023-11-11
  • MySQL视图的概念和操作函数详解

    MySQL视图的概念和操作函数详解

    对MySQL数据库的查询,除了基本的查询外,有时候需要对查询的结果集进行处理,下面这篇文章主要给大家介绍了关于MySQL数据库基本SQL语句教程之高级操作中视图的相关资料,需要的朋友可以参考下
    2023-03-03
  • 从ibd文件恢复MySQL数据的操作步骤及常见错误

    从ibd文件恢复MySQL数据的操作步骤及常见错误

    MySQL数据恢复是数据库管理中的一项重要任务,尤其是在遭遇意外数据丢失、硬件故障或软件错误时,下面这篇文章主要给大家介绍了关于从ibd文件恢复MySQL数据的操作步骤及常见错误,需要的朋友可以参考下
    2024-08-08
  • mysql实现随机查询经验谈

    mysql实现随机查询经验谈

    官方文档中进行说明:Order By和RAND()连用,会多次扫描表,导致速度变慢,下面看下一些测试详解
    2013-10-10
  • mysql命令行如何操作

    mysql命令行如何操作

    这篇文章主要介绍了mysql命令行如何操作,还为大家分享了mysql添加环境变量的方法,感兴趣的小伙伴们可以参考一下
    2015-11-11
  • 关于Mysql的InnoDB锁概述

    关于Mysql的InnoDB锁概述

    这篇文章主要介绍了关于Mysql的InnoDB锁概述,对于更新操作(UPDATE、INSERT、DELETE),InnoDB会自动给涉及到的数据集加排他锁,需要的朋友可以参考下
    2023-05-05

最新评论