联合索引(复合索引)在B+树上的结构

本文探讨了在MySQL INNODB中,B+树如何表示联合索引(复合索引)的问题。通过示例说明了如何根据col3和col2创建联合索引,并解释了最左原则在查找过程中的作用。当按COL3=‘Alice’和COL2=34查询时,先找到COL3的节点,再依据COL2定位具体记录。而WHERE COL2=34的查询则无法利用此联合索引,需全表扫描。


这几天看了B系列树和数据库索引相关的一些知识,看完这篇文章之后《MySQL索引背后的数据结构及算法原理

收获很大,了解了很多知识,随后也产生了一个想法:联合索引 对应的 B+ 树 是一个什么样子的结构。带着这个想法各种百度

也没得到自己想要的答案,那我就把我的想法写下来。

对于这块知识,我也是刚入门,如果有大神看到我的想法不对,还请多多指正。


这里以MySql INNODB为例,MyISAM道理是一样的。然后先从原文搬几个图过来:


这是一张表格,col1 是主建,col2和col3 是普通字段。那么主索引 对应的 B+树 结构是这样子的:



也可以是这样子的,这是我画的:



现在呢,对col3 建立一个单列索引,原文图:



看完这个图也是可以理解的,那么想法来了,如果对 col3 和 col2 建立 联合索引,那么 B+ 树会是一个什么样子的呢?

首先可以肯定的是,肯定只有一棵树,又因为 最左原则的存在,那么带着这个想法自己试着画了下:


建索引语句 CREATE INDEX IDX_XXX ON TABLE(COL3, COL2);

先根据col3 排序,在根据 col2 排序,如上图。

原文例子中的数据没有重复数据,为了更好的理解,我自己改了下:


红色框是改动的地方,把col3 改成有重复数据了,然后 还是对 col3 ,col2建立联合索引,那么 B+树 如下:


红色框是和原来不一样的地方。

联合索引在查找的时候,比如要找 Alice,34 这条记录 WHERE COL3 = 'Alice' AND COL2 = 34

先根据col3 查找 Alice ,找到了2条记录,在根据col2 查找 34,然后获取到主键 15 ,在根据主键去查找 主索引。

如果 是 WHERE COL2 = 34,由于只有联合索引 (col3, col2),没有col2 的单列索引。

那么查找的时候,就没法根据上面的这棵树来查找 ,只能全表扫描。

所以为什么会有最左原则,就是因为 B+树 是根据最左边的字段构建的,我的想法是这样子的。

如果不对,一定要帮忙批评指正啊。



### 联合索引的定义与实现机制 在数据库系统中,**联合索引**(也称为复合索引)是指基于多个列构建的索引结构。这种索引方式允许在多个字段上同时建立排序和查找优化机制,从而提高多条件查询的效率。在 InnoDB 存储引擎中,联合索引是通过 B+ 结构实现的,其构建方式遵循字段顺序原则,即索引首先按照第一个字段排序,在第一个字段相同的情况下再按第二个字段排序,依此类推[^4]。 B+ 作为索引结构,其内部节点仅存储键值,而所有实际数据记录都集中在叶子节点中,并且这些叶子节点之间通过指针连接形成一个有序链表。对于联合索引而言,每个索引条目包含多个字段的组合值,并按照这些字段的顺序进行排列。例如,建立 `(a, b)` 的联合索引后,索引将根据 `a` 和 `b` 的联合值进行排序,这使得在查询时可以高效支持 `WHERE a = 'value' AND b = 'another'` 类型的精确匹配,同时也适用于 `WHERE a > 'value'` 这样的范围查询[^5]。 联合索引的设计需考虑字段的使用频率和查询模式。如果某两个字段经常一起出现在查询条件中,则建议建立联合索引;若它们各自独立使用频率较高,则应分别建立单列索引。这种方式能够避免不必要的索引冗余并提升查询性能。 ```sql -- 示例:创建联合索引 CREATE INDEX idx_name_age ON users (name, age); ``` 在实际执行查询时,MySQL 查询优化器会根据索引的最左前缀原则决定是否使用联合索引。也就是说,只有当查询条件中包含联合索引的第一个字段时,才可能利用该索引进行高效检索。例如,`WHERE name = 'John'` 可以使用上述 `(name, age)` 索引,而 `WHERE age = 30` 则不会使用该索引[^4]。 此外,由于 B+ 的有序性,联合索引在处理范围查询时也具有显著优势。例如,以下 SQL 语句可以高效地利用联合索引 `(name, birthday, phone_number)` 来定位符合条件的记录区间: ```sql SELECT * FROM person_info WHERE name > 'Asa' AND name < 'Barlow'; ``` 这种结构确保了在遍历索引时,能够快速定位到起始点并沿着叶子节点链表连续读取满足条件的数据,从而大幅提升查询效率[^5]。 ---
评论 36
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值