各种索引的比较和MySQL数据库索引的选择
哈希索引
通过一个哈希函数,把值映射到某个区间的某个位置,读取的时候,也是通过找到映射位置并进行读取,平均的查找复杂度为O(1)。即对索引的key进行一次hash计算就可以定位出数据存储的位置。
典型的应用就是HashMap的底层实现,就是把key通过做一个哈希操作得到一个哈希值,然后再用这个哈希值对HashMap底层的数组长度取余,余数便是数组下标,数组所存的元素一般是一个链表,链表存储着哈希到这个位置的元素。如下图
哈希索引的优点:做等值查询(=,in)的时候很快,添加或者删除单个确定的元素很快;缺点在于哈希表中的元素不一定按顺序排列,无法做区间查询,哈希索引这种结构其实只适合等值查询的场景。
有序数组索引
如下图,相当于数组元素按照身份证号有序排列,要查询数据可以用二分查找,时间复杂度也是O(logN),区间查询的速度也非常快。
缺点:由于有序数组对查询友好,对插入删除操作不友好,如果插入删除数据的话,很可能要移动大量数据,开销非常大,所以其实有序数组索引只适合存储静态数据,就是存不怎么变的数据。
搜索树索引
树形的索引,比如二叉搜索树,多路平衡树等。优点是可以支持快速查找,也支持节点的插入和删除操作。典型的有两种:
B树索引:
叶子节点具有相同的深度,叶节点的指针为空
所有索引元素不重复
节点中的数据索引从左到右递增排列
B+树索引:
非叶子节点不存储data,只存储索引,这样的话,相同的空间就可以存储更多的索引
叶子节点包含所有的索引字段
叶子节点用指针连接,可以提高区间访问性能,一次区间查询只要查出区间的两个端点,然后遍历端点间的区间即可。
MySQL(InnoDB)底层为何会选B+树作为索引呢
然后我们就可以思考,MySQL底层为何会选择B+树作为索引。首先我们可以来看,如何选择二叉树作为索引的底层实现会怎样,举一个极端的例子,假设你是对递增的主键建立二叉树索引的话,很可能这棵树就只有一支,然后查询的时间复杂度也是O(N),这样就相当于链表没有被优化。
然后我们就可以考虑二叉平衡树,典型的有红黑树,红黑树相当于叶子节点只能存储一个值,然后表中元素非常多,那么这颗红黑索引树的高度会非常大,如果树的高度过大的话,可能就会造成磁盘IO频繁的情况,由于磁盘访问会有移动磁盘臂这种物理上的时间成本,所以一定会比内存访问更慢,所以我们需要一种更好的平衡树结构来尽量减少树的高度。
最后考虑一下,满足这种要求的平衡树数据结构也就B树和B+树。B树的特点是叶子节点和非叶子节点都存有值的信息,然后叶子节点之间没有指针连接。B+树的特点是叶子节点之间有指针连接,非叶子节点之中只存key,不存value。首先,B+树非叶子节点只存key,不存value,所以单个节点占用的物理内存更小,所以同样的内存空间,使用B+树可以存储更多的节点,一个页空间中能存更多的节点信息就意味着更少的访问磁盘次数,这是选择B+树的原因之一,二就是B+树叶子节点之间用指针连接,区间查询,只需要查找两个端点的位置,然后在两个端点之间挨个遍历即可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!