MySQL索引 索引的作用:提高查询效率
常见的索引结构:哈希表、有序数组、搜索树
哈希表:key-value 把值放在数组里,用一个哈希函数把 key 换算成一个确定的位置,然后把 value 放在数组的这个位置
有序数组:按照顺序存储,查询用二分法就可以快速查询,时间复杂度O(log(N)) 查询效率高,更新效率低
二叉搜索树:每个节点大于左侧子节点,小于右侧子节点,查询效率O(log(N)),维护二叉树的平衡性O(log(N))
数据库库大多采用N叉树,因为由于树高,二叉树访问一个行的时间就是树高*10ms的时间,太慢了。N叉树的话,一个整数的字段索引为例,这个N差不多是1200,当这棵树高是4时,就差不多可以存储1200的3次方个值了。而且最多也就访问3次磁盘
InnoDB采用的是B+树的数据结构
索引类型分为主键索引和非主键索引,主键索引的叶子节点存的是整行数据。在 InnoDB 里,主键索引也被称为聚簇索引(clustered index)。非主键索引的叶子节点内容是主键的值。在 InnoDB 里,非主键索引也被称为二级索引(secondary index)
基于主键索引和普通索引的查询有什么区别?基于非主键索引的查询需要多扫描一棵索引树。因此,我们在应用中应该尽量使用主键查询。
索引维护:如果在添加新数据时发现数据页已经满了,根据 B+ 树的算法,这时候需要申请一个新的数据页,然后挪动部分数据过去。这个过程称为页分裂。在这种情况下,性能自然会受影响。除了性能外,页分裂操作还影响数据页的利用率。原本放在一个页的数据,现在分到两个页中,整体空间利用率降低大约 50%。当然有分裂就有合并。当相邻两个页由于删除了数据,利用率很低之后,会将数据页做合并。合并的过程,可以认为是分裂过程的逆过程
由于 InnoDB 是索引组织表,一般情况下我会建议你创建一个自增主键,这样非主键索引占用的空间最小(如果用整型做主键,则只要 4 个字节,如果是长整型(bigint)则是 8 个字节)
回表:当我们根据非主键索引时会查询到该数据对应的主键,然后根据该主键查询到主键的索引树,这个过程称之为回表
覆盖索引:如果查询条件使用的是普通索引(或者是联合索引的最左侧字段),查询结果是主键或者是联合索引的字段,不需要回表,直接返回结果,减少IO读写,提高读写效率
最左前缀:联合索引的最左N个字段,也可以是字符串索引的最左M个字符
联合索引:如果已经有联合索引(a,b),那么就不需要在单独创建索引a,所以在我们创建联合索引时,应当安排好索引字段的顺序,第一原则是,如果通过调整顺序,可以少维护一个索引,那么这个顺序往往就是需要优先考虑采用的
索引下推:MySQL 5.6 引入的索引下推优化(index condition pushdown), 可以在索引遍历过程中,对索引中包含的字段先做判断,直接过滤掉不满足条件的记录,减少回表次数
无索引下推:
有索引下推: