索引的底层实现——高性能Mysql(第五章笔记2)

B+树索引的使用

根据上一篇文章,我们已知,Mysql施加索引的底层结构是B+树(innodb),B+树是根据某一值来进行排序的。

我们日常使用中,索引可以引用了很多列,而不是单一列的索引。

1、如果不是按照索引的最左列开始查找,则无法使用索引
2、不能跳过索引中的列,否则生效的只能是索引左侧没跳过的列。
3、如果查询中有某个列是范围查询,则其右边的列都无法使用索引优化查找。

上面三条意味着,索引中列的顺序,至关重要。

聚簇索引、非聚簇索引

我还以为聚簇索引会是什么新的数据结构,不是的,它指的是实现B+树的内容构成的不同。聚簇索引就是一个B+树的索引(Innodb)。

在Innodb,聚簇索引是根据主键值自动生成的,也叫主键索引,叶子节点存的就是每一行的值。懂了吧,Innodb的每张表的存储形式,本身就是一个B+树。

其他我们自己加的自定义索引,都叫做辅助索引,也叫做非聚簇索引,也叫二级索引,也叫非主键索引。。。。

明明就这么简单的东西,非得搞上这么多术语,显得很高大上的样子。个人觉得这种简单的概念表就不用加上这种术语索引了,而且重复构造了索引,服了。

如果没有唯一主键,或者没有唯一标识的数据列,Innodb会自动添加一个6字节(差不多281万亿条长度)的自增主键。

辅助索引的叶子节点的值,是主键。

所以我们通过辅助索引查找的话,会先去找辅助索引的B+树,得到主键值,然后再去聚簇索引找到那一行的值。

这也是为什么Innodb不喜欢主键值太长,也不喜欢主键值杂乱无意义的原因了。

主键值太长,所有的辅助索引就会很大。主键杂乱无意义,那么不好构建聚簇索引。

我们以后设计主键,尽量使用自增整数吧。

哈希索引

只有Memory引擎显式支持哈希索引(NDB集群所有也支持)。

Innodb引擎有个特殊的功能,叫做自适应哈希索引(adaptive hash index),当Innodb注意到某些索引值被使用的非常频繁的时候,会在内存中,基于B-Tree的索引上,自行创建一个哈希索引,这个行为不受用户控制,但是可以被手动关闭

哈希索引,就是为索引内的所有列计算一个哈希码。

只有精准匹配所有所有列的查询才有效。如果不同行的数据的哈希码的值 相同,则链表形式存放。

跟Hash表没啥不同。

哈希索引的缺陷:这里的实现无法sorted(按照索引排序),也不支持部分匹配。

自行创建哈希索引

我们也可以自行创建自适应哈希索引,手动为每一行计算哈希值。比如使用CRC32()函数。

为啥不用SHA1()或者MD5()呢?因为这两个函数计算出来的哈希值是非常长的。。。

还可以使用FNV64()函数,速度快,冲突比CRC()少很多。

空间数据索引(R-Tree)

这个空间索引,不得不让人想起redis的geo数据类型。也是经典存经纬度。

什么是R-Tree

什么是R树

R-Tree不仅使用平面经纬度,也适合高纬度搜索。

mysql需要使用MBRCOUNTAINS()来维护地理数据。但支持并不完善,多数人不会使用它。

全文索引

页码299

这种类型的索引,在搜索引擎比较常见。

我们可以试想使用场景,一个搜索框。

输入关键词,输出跟这关键词相关的所有数据。

如果这些相关数据都超级无敌长,难道我们要一个一个比较过去吗?想想也不现实吧。

所以,这不是一种精确查询,而是一种相似度查询

在mysql中要良好使用的话,最好搞个插件扩展下全文索引的功能。意思就是mysql写的代码还有大的进展空间呗。

有两层索引,一层是关键词,一层是文档指针。

整个索引中出现次数最小的词语,那么这个词语的相关度就很高,如果索引里这个词出现次数很多,那么这个词甚至都不会被搜索。界限大概是1半。

select film_id,title,RIGHT(desciption,25),MATCH(title,description) AGAINST('factory casualties') AS relevance FROM XXXX WHERE MATCH(title,description) AGAINST('factory casualties');

先简单贴一下关于全文索引的示例吧,MATCH(title,description) AGAINST(‘factory casualties’) AS relevance 这句话计算了两个列(title,description)关于’factory casualties’关键词的相关度

多次调用这种语句不会重复计算。

只有查询的列完全等于全文索引的列,才会使用全文索引。

全文索引的内容还挺多的,可能只会会再增加一章专门讲这个。

分形树索引

百度百科:分形树索引与B树不同的是,分形树索引在每个节点有缓冲器,这允许插入、删除和其他变化被存储在中间位置。缓冲器的目的是调度硬盘写入,使得每次写入执行大量有用的工作,从而避免B树最坏情况性能,其中每个磁盘写可以改变磁盘上的少量数据。

算是对B+树的增强吧。

覆盖索引

这货也不是什么新的数据结构,也是B族的树。

重点指的是,如何设置索引包含的列,要查询的值筛选的条件,在同一个索引里面。因为这样,查询的值,会存在辅助索引文件处。就不用再去找一遍聚簇索引。相当于用空间换时间了。

参考:覆盖索引

索引的用处,何时使用索引

综上,我们可以很明显的感觉出,索引是在数据的基础上,构建了不同的数据结构,能够快速的定位到需要查询的数据。
我们需要均衡构建索引的成本以及使用索引带来的增益。
如果表的量很小,那么就不需要使用索引。
如果表的数量特别多,那么单单使用索引可能不够,还可以使用分表、分区一起使用。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

rgbhi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值