什么是索引?
索引的出现就是为了提高数据查询的效率。
索引的常见模型
索引的出现时为了提高查询效率,但是实现索引的方式却又很多种,其中常见的有:哈希表、有序数组和搜索树。
哈希表:
一种以键-值存储数据的结构,只需要输入待查找的值key,就可以找到其对应的值value。哈希的思路很简单,把值放在数组里,用一个哈希函数把key换算成一个确定的位置,然后把value放在数组的这个位置。
有可能出现多个key值经过哈希函数的换算会出现同一个值的情况。处理这种情况的一种方法是拉出一个链表。
哈希表哈希表结构的使用场景
从上图可以看出哈希表索引的值并不是递增的,这样做的好处是增加新的User时速度会很快,只需要往后追加。但缺点是,因为不是有序的,所以哈希索引做区间查询的速度是很慢的。
哈希表这种结构适用于只有等值查询的场景,比如memcached及其他一些Nosql引擎。
有序数组
有序数组因为是有序的数值存储,在等值查询和范围查询场景中的性能是非常优秀的
有序数组适用场景
如果仅仅是看查询效率,有序数组就是最好的数据结构了。但是在需要更新数据的时候就麻烦了,
因为往中间插入一个记录就必须要挪动后面所有的记录成本太高,所以,有序数组索引只适用于静态存储引擎。
二叉索引树
二次叉搜索树的特点是:每个节点的左儿子小于父节点,父节点又小于右儿子。以下图为例子,如果要查ID_card_n2的话,按照图中的搜索顺序就是按照UserA->UserC->UserF->User2这个路径得到,这个时间复杂度是O(log(N))。
当然为了维持O(log(N))的查询复杂度,就需要保持这颗树是平衡二叉树,为了 做这个保证,更新的时间复杂度也是O(log(N))。
二叉树N叉树
多叉树就是每个节点有多个儿子,儿子之间的大小保证从左到右递增。二叉树是搜索效率最高的,但是实际上大多数的数据库存储却并不使用二叉树。其原因是,索引不止存在内存中,还要写到磁盘上。为了让一个查询尽量少地读磁盘,就必须让查询过程访问尽量少的数据块。那么,我们就不应该使用二叉树,而是要使用“N叉”树,这里,“N叉”树中的"N"取决于数据块的大小。
InnoDB的索引模型
在InnoDB中,表都是根据主键顺序以索引的形式存放的,这种存储方式的表称为索引组织表。又因为前面我们提到的,InnoDB使用了B+树索引模型,所以数据都是存储在B+树中的。
每一个索引在InnoDB里面对应一颗B+树。
举例:
假设,我们有一个主键列为ID的表,表中有字段K,并且在K上有索引
InnoDB的索引组织结构从图中可以看出,根据叶子节点的内容,索引类型分为逐渐索引和非主键索引。
主键索引的叶子节点存的是整行数据。在InnoDB里,主键索引也被称为聚簇索引。
非主键索引的叶子节点内容是主键的值。在InnoDB里,非主键索引也被称为二级索引。
主键索引和普通索引的区别?
索引维护
自增主键的适用场景
自增主键是指自增列上定义的主键,在建表语句中一般是这么定义的,NOT NULL PRIMARY KEY AUTO_INCREMENT。插入新记录的时候可以不指定ID的值,系统会获取当前ID最大值加1作为下一条记录的ID值。
也就是说,自增主键的插入数据模式,正符合了我们前面提到的递增插入的场景。每次插入一条新记录,都是追加操作,不涉及到挪动其他记录,也不会触发叶子节点的分裂。
覆盖索引
1、selec的数据列只用从索引中就能够取到,不必从数据表中读取,换句话说查询列要被所使用的索引覆盖;
2、索引是高效找到行的一个方法,当能通过检索索引就可以读取想要的数据,那就不需要再到数据表中读取行了。如果一个索引包含了满足查询语句中字段与条件的数据就叫做覆盖索引;
3、是非聚集组合索引的一种形式,它包括再查询里的select、join和where子句用到的所有列。
不是所有类型的索引都可以成为覆盖索引。覆盖索引必须要存储索引的列,而哈希索引、空间索引和全文索引等都不存储索引列的值,所以MySQL只能使用B-Tree索引做覆盖索引
最左前缀原则
在建立联合索引的时候,需要考虑如何安排索引内的字段顺序,因为可以支持最左前缀,所以当已经有了(a,b)这个联合索引后,一般就不需要单独再a上建立索引了。因此,第一原则是,如果通过调整顺序,可以少维护一个索引,那么这个顺序往往就是需要优先考虑采用的。
网友评论