聊聊MySql的索引

0 前言

  数据库对于小白最激动人心的就是索引了,mysql主要使用B+树和Hash两种方式来实现索引。不同于容易理解的,功能相对单一的hash索引,B+数实现的索引的特性就丰富很多。聚集索引,覆盖索引,范围搜索优化都是基于B+树的特性实现的。今年我们就来聊一聊mysql的索引技术。

1 索引分类

  mysql的索引从数据结构可以分为B+树索引,Hash索引,空间索引和全文索引(后两种不展开,主要介绍前面两种)。hash索引能实现高速的精确搜索,这是其他索引不能比的。而B+树索引由于其数据结构的特点,使得其支持丰富的索引特性,优化搜索。

1.1 hash索引

  如果你了解过java的HashMap,或者HashSet,那么理解hash索引就很简单了,其实现原理大同小异聊聊HashMap,这里就不在展开。
  hash索引每个节点只存储hash值和行指针(hash值对应键所在行的物理地址),不存储键的字段值。所以不能作为覆盖索引,也不能用于排序,范围搜索,部分前缀搜索。而这些性能正是B+树索引支持的。不过你也应该认识到,hash索引的精确搜索的性能是B+树索引不能实现的。

1.2 B+树索引

  希望了解B+树索引,那么不得不先了解B+树。B+树是一种n叉排序树,即每一个节点可以有多个孩子,而数据存储在叶子节点。通过减少搜索过程中的比较此处,提升搜索性能。通常用于数据库和操作系统的文件系统中。不同于B树,B+树的叶子节点包含一个指向下一个节点的指针,方便叶子节点的范围遍历。B+树介绍
  mysql的InnoDB和MyISAM都支持B+树索引。但是其存储方式略有不同。InnoDB的主索引为聚集索引,而MyISAM的索引为非聚集索引。此外B+树索引能够实现覆盖索引,这是B+树的特点,索引InnoDB和MyISAM都支持。不过在使用mysql的B+树索引时,要注意索引的前缀,复合索引要注意字段的顺序。

2 索引策略

2.1 聚集索引

  InnoDB将通过主键聚集数据,如果没有主键,会选择一个唯一(unique)的非空(not null)索引替代。如果没有这样的索引,会隐式创建一个主键来作为聚集索引。
  聚集索引的每个叶子节点都包含主键值、事务ID、用于事务和MVCC的回滚指针以及所有剩余列。而且由于B+树在磁盘中的存储方式本身就是顺序存储的,所以你会发现聚集索引的表数据在磁盘中的存储方式是依据主键顺序依次存储。这样带来的好处是,当使用聚集索引的主键实现范围搜索或者如groupby这样的操作,能减少I/O操作的次数。不过随之而来的缺点就是插入删除操作的复杂度也增加了。
  而非聚集索引(MyISAM),叶子节点的存储的是主键值和主键对应行的磁盘物理地址。虽然这样没有了聚集索引带来的好处,但是插入数据就可以在数据末尾插入了。因为维护索引和磁盘中存储数据行没有太大的联系。
  注意,一张表只能有一个聚集索引,这是很好理解的,因为数据聚集方式毕竟只能存在一种。而InnoDB的二级索引(除了主索引外的B+树索引),叶子节点储存的不是行指针。使用主键值当指针可能会让二级索引占用更多的空间,但是换来的好处是,InnoDB中的数据在移动时无需更新二级索引中的这个指针。

2.2 覆盖索引

  覆盖索引使得只访问索引的查询会很快。从之前的讨论中可以发现B+树会存储主键值。那如果你最终希望获得的数据只是主键值或者主键值集合,那么通过访问索引就可以了,而无需再去访问磁盘中的数据行。而索引很可能就存储在内存中。即使索引存储在磁盘中,由于索引的大小远远小于实际数据存储的大小,索引I/O的操作也会减少。如果从这个层面来看,非聚集索引在覆盖索引层面的性能可能是好于聚集索引的。你想想看这是为什么!

2.3 复合索引

  复合索引也就是多列索引,即索引包含多个列。还有一种方式使得多个列都为索引那就是为每个列都创建一个单独的索引,但是这是否是好的方式呢?这得看你的业务需求了。由于复合索引依赖于列的顺序,所以当这种依赖影响到你的业务需求,那么使用后者吧。但如果你的操作中包含对两个索引结果的合并操作,那么请使用复合索引吧(注意索引的顺序)。举个简单的例子:表有两个字段,name,age。如果你的需求仅仅是搜索name=”Mike”的人,或者仅仅搜索age=”19”的人,那么复合索引根本没有必要。反而如果你创建了(age,name)这样的复合索引,再来搜索name=”Mike”,由于索引的前缀性的影响,你并不得得出好的搜索结果。但是如果你需要这样的搜索,age=19,并且name=”M*”的人,复合索引的性能高于两个单索引下age=”19”&& name=”M*”的搜索。(以上都是伪代码)。究其原因是复合索引能通过前面的索引项减小搜索范围,而多个单列索引并不能,只能通过每个索引的搜索结果集合并得到最终的结果。

3 参考资料

《高性能MySql》

你可能感兴趣的:(数据库,索引,mysql)