4&5深入浅出索引 - MySQL实战45讲学习笔记

本文深入探讨了数据库索引的原理和应用,包括哈希表、有序数组、搜索树等常见模型,以及InnoDB存储引擎的B+树索引模型。介绍了索引维护、覆盖索引、最左前缀原则和索引下推等概念,帮助读者理解索引如何提高查询效率。

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

说到索引,大家肯定都不陌生。比如使用sql查询的时候比较慢,这时我们会考虑给某个字段加上一个索引,存储引擎通过使用索引可以加快搜索的速度。那么,到底什么是索引?索引是如何工作的呢?本章就来讲一讲这些东西。

我觉得实战45讲4,5两章的内容比较好理解,内容也不是很多,所以就把这两章合整理出来了。。

用最通俗的话形容索引,就是:索引就像是一个目录,能让我们快速找到数据项。
比如,大家都很熟悉的InnoDB的索引是B+树,熟悉B+树 的童鞋很容易理解索引的作用,就是为了查询。
那么,还有一些其他的索引模型,下面来看看:

索引的常见模型

这里介绍三种常见的、简单的数据结构:哈希表、有序数组、搜索树。下面从使用的角度来讲:

1. 哈希表

一种以键-值(key-value)存储数据的结构,我们只要输入待查找的值即key,就可以找到其对应的值即Value。

哈希表查找的思路:用一个哈希函数把key换算成一个确定的位置,然后把value放在数组的这个位置,(value其实是数据项的地址,得到value后,value指向的数据项才是我们想要的数据)。

当然,哈希表是有可能会冲突的,处理冲突的一个方法就是在冲突的位置上拉出一个链表,数据项依次加入链表的头,称为拉链法。

优点:等值查询速度快
缺点:区间查询很慢

原因:等值查询速度快很容易理解,因为通过哈希函数将key换算成数组位置,直接取该位置的数据即可。

那为什么区间查询很慢呢?
因为数组里的value不是顺序存放的,每个key通过哈希函数映射出来的数组位置是随机的。所以如果查询一个区间内的所有数据项,需要根据key一个一个去映射,这样就减慢了速度。

所以,哈希表这种结构适用于只有等值查询的场景,比如Memcached及其他一些NoSQL引擎。

2. 有序数组

优点:而有序数组在等值查询和范围查询场景中的性能就都非常优秀

等值查询:因为数据的有序存放在数组中,所以可以使用二分法来查询,复杂度O(logn)
区间查询:先等值查询区间第一个数据,然后顺序遍历数组取得后面的数据。

缺点:只查询可以说是最好的数据结构了。但是,如果要增加或删除数据可就麻烦了,要挪动后面所有的数据,更新时间太慢。

所以,有序数组索引只适用于静态存储引擎,比如你要保存的是2017年某个城市的所有人口信息,这类不会再修改的数据。

3. 搜索树

二叉搜索树是我们课本的经典数据结构。

它的特点:左儿子小于父节点,父节点小于右儿子。查询的复杂度是树的高度O(logn)。为了维持这个查询复杂度,我们也要保证这个二叉搜索树是平衡二叉树,所以,插入删除节点后要调整树,使其平衡,更新的时间复杂度也是O(logn)。

当然,树不止有二叉,还可以是m叉,代表一个节点有多个儿子,儿子之间保证从左到右递增。

二叉树的查询和更新的性能都非常好,但是实际中大多数的数据库存储结构并不是二叉树,这是为啥呢?
原因是:索引不是全部存储在内存中,有一大部分节点存储在磁盘中,只有需要了才会写入内存。

你可以想象一下一棵100万节点的平衡二叉树,树高20。一次查询可能需要访问20个数据块。在机械硬盘时代,从磁盘随机读一个数据块需要10 ms左右的寻址时间。也就是说,对于一个100万行的表,如果使用二叉树来存储,单独访问一个行可能需要20个10 ms的时间,这个查询可真够慢的。

所以,为了让一个查询尽量少的读取磁盘,就要访问尽量少的数据块(节点),也就是让树的高度变低,所以一般使用m叉树。

以InnoDB的一个整数字段索引为例,这个N差不多是1200。这棵树高是4的时候,就可以存1200的3次方个值,这已经17亿了。考虑到树根的数据块总是在内存中的,一个10亿行的表上一个整数字段的索引,查找一个值最多只需要访问3次磁盘。其实,树的第二层也有很大概率在内存中,那么访问磁盘的平均次数就更少了。

N叉树由于在读写上的性能优点,以及适配磁盘的访问模式,已经被广泛应用在数据库引擎中了。

不管是哈希还是有序数组,或者N叉树,它们都是不断迭代、不断优化的产物或者解决方案。数据库技术发展到今天,跳表、LSM树等数据结构也被用于引擎设计中,这

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值