mysql B+树索引

本文介绍了索引作为数据结构的作用,对比了数组、链表、二叉树等查找效率。重点讲解了B-树和B+树的区别,强调B+树在MySQL中降低IO操作和支持范围查询的优势。还提到了聚簇索引和非聚簇索引的概念,并给出设计数据库表的实用建议,包括选择合适的数据类型、创建唯一和复合索引等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

索引

索引是什么?索引是一种数据结构,是一种能够帮助我们快速定位到数据的数据结构。最长常见的数据结构有数组、链表、二叉树、红黑树。

数组我们如何定值查询?只能遍历比较了,最差的情况下要遍历所有元素,时间复杂度O(n)。

链表如何定值查找元素?那就更只能靠遍历每一个节点来实现了,时间复杂度O(n)。

二叉树如何查找元素?从根节点向下遍历,就查找二叉树来说,时间复杂度是O(log n)。
但是二叉树有一个问题,如果根节点是到叶子节点如果是顺序插入的话,二叉树就会变成一个线性的链表。
在这里插入图片描述
鉴于二叉树的缺点,我们需要一种平衡二叉树来提高我们的查询效率。
在这里插入图片描述
但是平衡二叉树还是有一个问题,当树的节点足够多的情况下,树的高度还是会很高,定值查询依然会有瓶颈。

B-树结构

在这里插入图片描述
B树为了保证树的高度不要太高于是对树的每个节点进行了横向的扩展,也即是每一个节点可以可以存放多个数据,那么这样来说,树的高度就可以降低了。这种横向扩展的结构我们称做为,虽然B树解决了树的高度问题,但是同时带来一个问题,那就是每个页里面都有存放数据,io操作时依然会带来很大的性能开销。

B+树结构

在这里插入图片描述
B+树像较与B树有两个改变

  1. 将数据只存在在叶子节点上
  2. 叶子节点上增加一个横向指针

数据存在叶子节点的好处?
根节点和中间节点就能存储更多的数据,mysql默认的页大小是16kb,如果根节点和中间节点不存放数据的话,就能存放更多的索引数据,就能减少磁盘的IO,比如上述结构的,11我们只需两次io就能真正的查询到数据。

叶子节点的横向指针的好处?
叶子节点的横向指针可以支持范围查询,像我们hash索引就不能支持范围查询。

聚簇索引和非聚簇索引
叶子节点的data存放了实际数据的就是聚簇索引,innerDB就是聚簇索引的实现,叶子节点的data只存放了数据的磁盘地址的就是非聚簇索引,myisam就是非聚簇索引的实现,想要真正定位到数据还要一次IO操作。

为什么innerDb希望我们建一个整形自增的主键索引?
整形的好处大概有两个,一个是方便比较,第二个是相对占用的空间小,自增的目的是为了减少树的旋转。

关于设计表的几个建议
  1. 建议使用innerDb引擎,支持事务、表锁、行锁、聚簇索引
  2. 最好有整形自增主键,强调一点根据数据量选用int或者bigint,尽量避免主键到头的尴尬
  3. 索引最好有唯一索引和复合索引搭配使用,不要滥建索引,会降低写的性能,树的旋转耗时
  4. 列字段占用空间越小越好,可以使用枚举来代替字符串
  5. 最好有create_time 和 update_time字段,方便定位问题
  6. 最好预留几个字段,方便扩展
  7. 字段备注越详细越好,方便后来者熟悉业务
  8. 数据表最好一次建好,后续执行DML会耗时,表越大越耗时,修改过程中会拒绝写操作
  9. 表字段不宜太多,可以垂直拆分成多个表
扫码关注公众号

在这里插入图片描述

<think>嗯,用户想比较MySQL中B+索引和哈希索引的优缺点及适用场景。首先,我需要回忆一下这两种索引的基本结构和工作原理。B+索引是一种多路平衡查找,而哈希索引则是基于哈希表实现的。两者的结构差异会导致不同的查询性能表现。 根据引用[3],B+索引适合范围查询和排序,而哈希索引在等值查询上更快。那用户可能需要知道什么情况下选择哪种索引更好。比如,如果应用中有很多范围查询,B+更合适;如果是精确查找,哈希可能更高效。 接下来,要考虑它们的存储结构。引用[4]提到B+的内部节点只存索引,不存数据,这样减少存储空间。而哈希索引可能需要处理哈希冲突,这会影响性能。这点需要详细说明。 性能对比方面,B+的查询时间复杂度是O(log n),哈希则是平均O(1),但最坏情况可能退化为O(n)。但实际中哈希冲突管理好的话,还是高效的。不过B+在范围查询时效率更高,这也是为什么MySQL默认使用B+的原因之一。 使用场景的话,用户可能需要知道何时选择哈希索引。比如内存表或者需要快速查找键值的场景。而B+适用于需要排序、分组或者范围查找的情况,比如订单时间范围查询。 另外,需要提到哈希索引不支持部分索引和覆盖索引,而B+支持,这点在优化查询时很重要。例如,如果查询只需要索引列,B+可以直接返回数据,而哈希需要回表。 还要注意MySQL的存储引擎支持情况,比如InnoDB的自适应哈希索引功能,用户可能不知道这个特性,可以解释一下。 最后,总结两者的优缺点,给出实际应用中的建议,帮助用户根据具体需求选择合适的索引类型。同时,确保回答结构清晰,分点明确,让用户容易理解。</think>### MySQL B+索引与哈希索引对比分析 #### 一、核心区别 1. **数据结构** - **B+索引**:多路平衡搜索,数据存储在叶子节点,形成有序链表[^4] 例如:$$ \text{非叶节点}(K_1,K_2,...,K_n) \rightarrow \text{叶节点}(D_1,D_2,...,D_n) $$ - **哈希索引**:基于哈希表实现,通过哈希函数将键值映射到桶位置 2. **查询模式** - B+支持$范围查询$(如`BETWEEN`、`>`、`<`)和排序操作 - 哈希索引仅支持$等值查询$(`=`、`IN()`),无法处理范围查询[^3] #### 二、性能对比 | 维度 | B+索引 | 哈希索引 | |------------|--------------------------|-------------------------| | 查询时间复杂度 | $O(\log N)$ | 平均$O(1)$,最差$O(N)$ | | 范围查询效率 | 高(顺序访问叶子节点)[^4] | 不支持 | | 排序性能 | 天然有序 | 需要额外排序步骤 | | 索引维护成本 | 插入/删除需要平衡 | 哈希冲突需处理链式结构 | #### 三、存储特性 1. **B+优势** - 支持$覆盖索引$(索引包含查询字段) - 内部节点不存储数据,节省空间[^4] 例如:$$ \text{存储效率}=1-\frac{\text{数据节点数}}{\text{总节点数}} $$ - 支持多列联合索引的最左前缀匹配 2. **哈希局限** - 无法使用索引完成排序 - 不支持部分索引(如`LIKE 'prefix%'`) - 哈希冲突会降低性能 #### 四、典型应用场景 1. **优先选择B+** - 订单系统的日期范围查询 ```sql SELECT * FROM orders WHERE order_date BETWEEN '2023-01-01' AND '2023-06-30' ``` - 需要`ORDER BY`的报表查询 - 联合索引查询(如`(last_name, first_name)`) 2. **适合哈希索引** - 内存表(MEMORY引擎)的高速等值查询 ```sql SELECT session_data FROM user_sessions WHERE session_id = 'a1b2c3' ``` - 数据仓库的精确匹配ETL过程 - InnoDB自适应哈希索引(自动缓存热点数据)[^1] #### 五、选择建议 1. **OLTP系统**:90%以上使用B+索引 2. **OLAP系统**:在明确只有点查询时考虑哈希索引 3. **混合负载**:使用InnoDB自适应哈希索引,自动平衡两者优势
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值