索引:
MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构。
概述:
索引依托于储存引擎的实现,因此每种储存引擎的索引不一定完全相同,并且每种存储引擎也不一定支持所有的索引类型,所有的存储引擎支持每个表最多16个索引,总索引长度至少为256个字节,mysql中的索引的储存类型主要是 B-Tree索引,Hash索引,不是全部但是这里直说这两种。
索引的分类
1,普通索引(单列索引):
2,唯一索引 :索引列的值必须唯一,但允许有空值
3,主键索引 :主键索引也是一种特殊的唯一索引,不允许有空值,一般就是主键
4,组合索引(多列索引,复合索引) :多列字段构成的一个索引,在查询过程中只有出现了多列中第一个字段才会被启用,遵循最左前缀原则
5,全文索引 :主要用来查找文本中的关键字,而不是直接与索引中的值相比较。fulltext索引跟其它索引大不相同,它更像是一个搜索引擎,而不是简单的where语句的参数匹配。
原理
当你在数据库中建立一个索引,数据库会很据它本身所支持的索引类型,为你建造一个对应的索引,所以我们必须明确的是,索引是存储引擎用于快速找到记录的一种数据结构,是一种数据结构,储存字段及数据的数据结构,下面我们详细介绍
B-Tree索引
B-Tree索引是最常用的,这里我们主要讲B-Tree和他的变种B+Tree
B-Tree索引
B树,没个节点都储存key和data,所有节点组成这颗树,并且叶子节点的指针为空,叶子节点比包括任何关键字信息
B+Tree
B树的变种不止B+树一个,但是这个使用最多,mysql最常用的就是B+Tree作为索引
B+树,非叶子节点是不含有data的,也就是他只含有字段信息,用于指明下一步的查找路径,全部的关键字信息以及指向含有这些关键字记录的指针都存在于叶子节点,且叶子节点本身依赖于关键字大小进行顺序链接,
一般在数据库系统或文件系统中使用的B+Tree结构都在经典B+Tree的基础上进行了优化,增加了顺序访问指针。
带有顺序指针的B+树索引结构,所以我们可以通过一个叶子节点遍历所有的叶子节点。
哈希索引
哈希索引就是采用一定的哈希算法,把键值换算成新的哈希值,检索时不需要类似与B-Tree那样从根节点到叶子节点的逐级查找,只需要一次哈希算法就可以了,这里要特别声明一下,不同的值经过哈希转换后是可能产生一样的值的,这就是哈希冲突,这里采用的就是拉链法处理,即每一个部分都是一个链表,储存的是所有满足这个要求的值。
哈希索引的优势:
等值查询:我相信大家都能理解,因为只需要经过一次哈希转换就可以(前提是没有大量重复的数据)
哈希不适用的场景:
1,不支持范围查询,因为哈希是无序存储的
2,不支持索引完成排序
3,不支持联合索引的最左前缀匹配原则
主要就是哈希存储是无序的,所以只适合等值查询
B-Tree和B+Tree的区别:
1,B树非叶子节点也储存关键字的具体数据,B+树,非叶子节点只作为索引作用,因此B树中非叶子节点不会与叶子节点含有重复的值,B+树会存在
2,B+树的叶子节点见存在指向关系,从小到大,B树叶子节点的指针为空
常见问题
为什么使用数据索引能提高效率:
1,数据索引的储存是顺序存储
2,在有序的情况下,通过索引查询一个数据是无需遍历索引记录的
3,极端情况下,数据索引查询的效率为二分查询效率,趋近于log(N)
为什么说B+树比B树更适合实际应用中操作系统的文件和数据库索引(主要考察两者不同)
1,B+的磁盘读写代价更低,因为B+树的内部节点没有储存关键字具体信息的指针,因此内部节点相对B树更小,如果把所有同一内部关键字存放在同一块盘中,那么盘块所能容纳的关键字数量也越多,一次性读入内存中需要查找的关键字也越多,相对于IO读写次数也就降低了;
2,B+树的查询效率更加稳定,任何关键字的查询都要走一条根到叶子节点的路径,路径长度相同,因此查询效率比较稳定
mysql联合索引
联合索引必须是两个或更多列以上的索引,对于联合索引,mysql从左到右使用索引的字段,即最左匹配原则,例如 key index(a,b,c),可以是通过abc,ab,a这三种方式查找;当最左侧是常量索引时,索引就十分有效
利用索引中的附加列,可以缩小搜索的范围,但使用一个具有两列的索引 不同于使用两个单独的索引。
什么情况下应该不建或少建索引
1,表记录太少
2,经常插入,删除,修改的表
3,数据重复且分布平均的表字段
4,经常和主字段一块查询的,但主字段索引值比较多的表字段