mysql数组索引_mysql之索引

索引的出现其实就是为了提高数据查询的效率,就像书的目录一样。

索引数据模型

一个表的数据行数越多,那么对应的索引文件其实也是会很大的,实际上也是需要存储在磁盘中的,而不能全部都放在内存中,所以我们在考虑选用哪种数据结构模型时,可以换一个角度思考,哪个数据结构更适合从磁盘中读取数据,或者哪个数据结构能够提高磁盘的IO效率。

可以用于提高读写效率的数据结构很多,常用的有哈希表、有序数组、完全平衡二叉搜索树、B树、B+树等数据结构。

MySQL中的索引是B+树实现的,MySQL为何选择使用B+树?得看看其他数据结构实现的索引的特点:

哈希索引

哈希的思路很简单,把值放在数组里。用一个哈希函数把 key 换算成一个确定的位置,然后把 value 放在数组的这个位置。

比如给name字段建立hash索引的情况下,首先数据库底层会计算name字段各行值对应的hash值作为数组下标,其中可能会有hash冲突,存储对应的那一行数据的地址。

当直接执行select * from users where name = 'tom';的时候,数据库会计算'tom'的hash值,得到数组下标,然后直接从数据中取出数据并拿到锁对应的那一行数据的地址,进而在数据表文件中查询那一行数据。

但是当执行select * from users where name > 'tom';时,索引将不再起作用。

因为哈希表并不是有序的,可以快速的精确查询,但是不支持范围查询。所以只适合做等值查询,区间查询的效率很低!好像字典里的索引去掉了排序。

另外多个 key 值经过哈希函数的换算,会出现同一个值的情况。处理这种情况的一种方法是,拉出一个链表。按顺序遍历,找到。

因为不是有序的,插入速度会很快,只需要往后追加。但缺点是哈希索引做区间查询的速度会很慢的,索引将不再起作用,相当于全表扫描了。

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

有序数组索引

就是按照索引字段的顺序保存的数组,用二分法就可以快速得到,这个时间复杂度是 O(log(N)) 。支持范围查询。

但是,在需要更新数据的时候或插入一个记录就必须得挪动后面所有的记录,成本太高。

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

二叉搜索树索引

二叉树数据结构1

二叉树数据结构2

二叉搜索树的特点是:每个节点的左儿子小于父节点,父节点又小于右儿子。这样如果你要查ID_card_n2 的话,按照图中的搜索顺序就是按照 UserA -> UserC -> UserF -> User2 这个路径得到。这个时间复杂度是 O(log(N)) 。

当然为了维持 O(log(N)) 的查询复杂度,你就需要保持这棵树是平衡二叉树。为了做这个保证,更新的时间复杂度也是 O(log(N)) 。

多叉树索引

树可以有二叉,也可以有多叉。多叉树就是每个节点有多个儿子,儿子之间的大小保证从左到右递增。比完全平衡二叉搜索树要 "矮"!

二叉树是搜索效率最高的,但是实际上大多数的数据库存储却并不使用二叉树。其原因是,索引不止存在内存中,还要写到磁盘上。

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

为了让一个查询尽量少地读磁盘,就必须让查询过程访问尽量少的数据块。那么,我们就不应该使用二叉树,而是要使用 “N 叉 ” 树。这里, “N 叉 ” 树中的 “N” 取决于数据块的大小。

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

N 叉树由于在读写上的性能优点,

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值