首先说说mySQL里面索引的类型:


从数据结构角度



1、B+树索引(O(log(n))):



2、hash索引:
a 仅仅能满足"=","IN"和"<=>"查询,不能使用范围查询
b 其检索效率非常高,索引的检索可以一次定位,不像B-Tree 索引需要从根节点到枝节点,最后才能访问到页节点这样多次的IO访问,所以 Hash 索引的查询效率要远高于 B-Tree 索引
c 只有Memory存储引擎显示支持hash索引






注意点:



MySql 常见存储引擎 InnoDB 和 MyISAM 都不支持 Hash 索引,它们默认的索引都是 B-Tree。但是如果你在创建索引的时候定义其类型为 Hash,MySql 并不会报错,而且你通过 SHOW CREATE TABLE 查看该索引也是 Hash,只不过通过   SHOW INDEXES FROM发现 该索引实际上还是 B+ Tree。



而INNODB又比较高级,发现如果对于B+树索引上如果创建hash索引能够提高速度,就会创建hash索引来提升效率。 这叫做自适应hash索引。









3、FULLTEXT索引(现在MyISAM和InnoDB引擎都支持了)



4、R-Tree索引(用于对GIS数据类型创建SPATIAL索引)



从物理存储角度



1、聚集索引(clustered index)



2、非聚集索引(non-clustered index)



从逻辑角度



1、主键索引:主键索引是一种特殊的唯一索引,不允许有空值



2、普通索引或者单列索引



3、多列索引(复合索引):复合索引指多个字段上创建的索引,只有在查询条件中使用了创建索引时的第一个字段,索引才会被使用。使用复合索引时遵循最左前缀集合



4、唯一索引或者非唯一索引



5、空间索引


另外关于索引的概念:稀疏索引 :对应文件中搜索码的每一个值都有一个索引记录(或索引项)。索引记录包括搜索码值和指向具有该搜索码值的第一个数据记录的指针

稠密索引  : 与稠密索引相反,稀疏索引只为搜索码的某些值建立索引记录


由于针对数据库来说,查询的主要开销是将数据块从磁盘之中读入到内存之中(按照块为单位),那么一旦将一个数据块放入内存之后,扫描这个数据块的时间是可以忽略的。因此数据库更加适合使用稀疏索引。



然后看看B+树的相关内容:

二叉树: 每个节点至多有两个儿子节点

红黑树: 二叉搜索树的改进版本,在插入,删除数据的时候多了一些将二叉树更加平衡的操作。


b树:好像就是二茶树,每个节点都存储了关键字key的信息

b-树: 平衡的多叉树,每个节点存储[2,M]个关键字key的信息,以及相应的导航

mysql innodb 支持自定义哈希索引 mysql innodb hash索引_子节点

 


(蓝色表示磁盘块,因此上图查询29这个,索引上面花费的磁盘IO是3次)


b+树:每个节点的儿子节点可以拥有超过2个子节点,B+树的非叶子结点只包含导航信息,key 信息只出现在叶子节点。 


mysql innodb 支持自定义哈希索引 mysql innodb hash索引_主键_02

 

为什么使用b+树而不是红黑树,因为很明显对于一次索引查找操作来说,红黑树的深度更大,需要更多的IO操作。为什么使用b+而不是b-,因为b+的key信息只出现在叶子节点,因此内存之中能放入的导航的信息更多。


还有一个概念:聚簇索引: 这是从物理上来讲,一种索引的存储方式。 一个索引上面不止有key信息,还有对应的行的信息。

InnoDB引擎中,一个聚集索引是必须的,如果没有定义主键,InnoDB首先会找一个唯一索引来做聚簇索引,如果无法找到这样的唯一索引,innodb也会自己隐含的建立一个聚集索引作为主键,因为InnoDB的主键索引还有个重要的功能就是行锁。  InnoDB的主键索引包含了行的全部信息,索引Key是主键值,索引Value是整行的值。而非主键索引索引Key是列值,索引Value是主键值,需要注意的是这里的value值并不是行的物理地址值。因此从非聚簇索引取数据,需要至少两次内存操作,第一次从非聚簇索引取得主键的值,然后通过主键的值取聚簇索引中寻找对应的行,从而获取行的数据。