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-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族的树。
重点指的是,如何设置索引包含的列,要查询的值跟筛选的条件,在同一个索引里面。因为这样,查询的值,会存在辅助索引文件处。就不用再去找一遍聚簇索引。相当于用空间换时间了。
参考:覆盖索引
索引的用处,何时使用索引
综上,我们可以很明显的感觉出,索引是在数据的基础上,构建了不同的数据结构,能够快速的定位到需要查询的数据。
我们需要均衡构建索引的成本以及使用索引带来的增益。
如果表的量很小,那么就不需要使用索引。
如果表的数量特别多,那么单单使用索引可能不够,还可以使用分表、分区一起使用。