mysql索引详解(总结)
上文《关于 mysql 施行流程的解析》中我们主要介绍了sql语句在server层的施行历程
我们再来剖析一下详细的语句在引擎层的施行步骤,CRUD的操纵都跟索引相关,我们先理解一下索引
索引
索引的显现其实就是为了提高数据查询的效力,就像书的名目
数据构造
常见的数据构造有 哈希表、有序数组和搜索树
哈希表是一种以键 - 值(key-value)储备数据的构造,我们只要输入待查寻的值即 key, 就可以寻到其对应的值即 Value。哈希的思绪很简便,把值放在数组里,用一个哈希函数 把 key 换算成一个位置,然后把 value 放在数组的对应位置
不成幸免地,多个 key 值经过哈希函数的换算,会显现统一个值的状况。处置这种状况的 一种办法是,拉出一个链表
哈希表这种构造适用于只要等值查询的场景
有序数组在等值查询和范畴查询场景中的机能就都非常优异
假如仅仅看查询效力,有序数组就很好。但是,在需要更新数据的时候就 费事了,你往中心插入一个记载就必需得移动后面所有的记载,成本太高
有序数组索引只适用于静态储备引擎
二叉搜索树的特点是:每个节点的左儿子小于父节点,父节点又小于右儿子
当然为了保持 O(log(N)) 的查询复杂度,你就需要保持这棵树是均衡二叉树。为了做这个 包管,更新的时间复杂度也是 O(log(N))
二叉树是搜索效力最高的,但是实际上大多数的数据库储备却并不使用二叉树。 其缘由是,索引不止存在内存中,还要写到磁盘上
为了让一个查询尽量少地读磁盘,就必需让查询历程拜访尽量少的数据块。那么,我们就不该该使用二叉树,而是要使用“N 叉”树。这里,“N 叉”树中的“N”取决于数据块的大小
N 叉树由于在读写上的机能长处,乃至适配磁盘的拜访模式,已经被广泛利用在数据库引擎中了
InnoDB 的索引模型
在 InnoDB 中,表都是按照主键次序以索引的情势存置的,这种储备方式的表称为索引组织表。 InnoDB 使用了 B+ 树索引模型,所以数据都是储备在 B+ 树中的
每一个索引在 InnoDB 里面临应一棵 B+ 树
按照叶子节点的内容,索引类型分为主键索引和非主键索引
主键索引的叶子节点存的是整行数据。在 InnoDB 里,主键索引也被称为聚簇索引
非主键索引的叶子节点内容是主键的值。在 InnoDB 里,非主键索引也被称为二级索引
基于非主键索引的查询需要多扫描一棵索引树(回表)。因此,我们在利用中应当尽量 使用主键查询
索引保护
B+ 树为了保护索引有序性,在插入新值的时候需要做必要的保护
假如新插入的 ID 值比本来的小,就相对费事了,需要逻辑上移动后面的数据,空出位置
而更糟的状况是,假如所在的数据页已经满了,按照 B+ 树的算法,这时候需要申请 一个新的数据页,然后移动部分数据过去。这个历程称为页分裂。在这种状况下,机能天然会受影响。
除了机能外,页分裂操纵还影响数据页的利用率。本来放在一个页的数据,此刻分到两个页中,团体空间利用率落低大约 50%。
当然有分裂就有合并。当相邻两个页由于删除了数据,利用率很低之后,会将数据页做合 并。合并的历程,可以认为是分裂历程的逆历程
自增主键的插入数据模式,正相符了我们前面提到的递增插入的场景。每次插 入一条新记载,都是追加操纵,都不触及到移动其他记载,也不会触发叶子节点的分裂。
而有业务逻辑的字段做主键,则往往不容易包管有序插入,这样写数据成本相对较高
主键长度越小,一般索引的叶子节点就越小,一般索引占用的空间也就越小
所以,从机能和储备空间方面考量,自增主键往往是更合理的选中
有没有什么场景适合用业务字段直接做主键的呢?还是有的。比方,有些业务的场景需求 是这样的:
1.只要一个索引;
2.该索引必需是独一索引。
这就是典型的 KV 场景
覆盖索引
假如施行的语句是 select ID from t ,这时只需要查 ID 的 值,而 ID 的值已经在 k 索引树上了,因此可以直接供给查询结果,不需要回表。也就是说,在这个查询里面,索引 k 已经“覆盖了”我们的查询需求,我们称为覆盖索引
由于覆盖索引可以减少树的搜索次数,显著晋升查询机能,所以使用覆盖索引是一个常用的机能优化手段
索引下推
知足最左前缀原则的时候,最左前缀可以用于在索引中定位记载。这时,你大概要问,那些不相符最左前缀的部分,会如何样呢?
MySQL 5.6 引入的索引下推优化, 可以在索引遍历过 程中,对索引中包括的字段先做推断,直接过滤掉不知足前提的记载,减少回表次数
最左前缀原则
不只是索引的全部定义,只要知足最左前缀,就可以利用索引来加快检索
在创立结合索引的时候,怎样安排索引内的字段次序?
这里我们的评估标准是,索引的复用能力。由于可以支撑最左前缀,所以当已经有了 (a,b) 这个结合索引后,一样就不需要独自在 a 上创立索引了。因此,第一原则是,假如通过调整次序,可以少保护一个索引,那么这个次序往往就是需要优先思考采纳的
前缀索引
利用最左前缀原则可以定义字符串的一部分作为索引。默许地,假如你创立索引的语句不指定前缀长度,那么索引就会包括整个字符串
但,这同时带来的亏损是,大概会增添额外的记载扫描次数,由于索引雷同需要进一步比力
使用前缀索引,定义好长度,就可以做到既节约空间,又不消额外增添太多的查 询成本
可以通过统计索引上有多少个不一样的值来推断要使用多长的前缀,从而减少扫描次数
前缀索引对覆盖索引的影响
使用前缀索引就用不上覆盖索引对查询机能的优化了,这也是你在选中可否使用前缀索引时需要思考的一个因素
倒序储备和hash储备
关于相似于邮箱这样的字段来说,使用前缀索引的结果大概还不错。但是,碰到前缀的区 分度不足好的状况时,我们要如何办呢?
第一种方式是使用倒序储备。假如你储备身份证号的时候把它倒过来存
第二种方式是使用 hash 字段。你可以在表上再创立一个整数字段,来留存身份证的校验码,同时在这个字段上创立索引
免费学习视频教程引荐:mysql视频教程
以上就是mysql索引详解(总结)的具体内容,更多请关注百分百源码网其它相关文章!