mysql小于3的索引_3.MySQL索引原理与使用原则

本章要点

1.索引原理

2.索引类型

3.使用原则

4.有关索引的几个概念

1. 索引原理

索引的出现其实就是为了提高数据查询的效率,就像书的目录一样。

本质就是:通过不断地缩小想要获取数据的范围来筛选出结果,同时把随机的事件变成顺序的事件。

1.1 索引的常见模型

常见的索引模型数据结构:哈希表、有序数组和搜索树。

哈希表:一种以键 - 值(key-value)存储数据的结构(Map),只要输入待查找的键即 key,就可以找到其对应的值即 Value。哈希的思路很简单,把值放在数组里,用一个哈希函数把 key 换算成一个确定的位置,然后把 value 放在数组的这个位置。不可避免地,多个 key 值经过哈希函数的换算,会出现同一个值的情况。处理这种情况的一种方法是,拉出一个链表。链表过长时,性能交叉,且不支持范围查询。

哈希表这种结构适用于只有等值查询的场景,比如 Memcached 及其他一些 NoSQL 引擎

有序数组:有在等值查询和范围查询场景中的性能就都非常优秀。利用二分查找算法进行查找效率很快(O(log(N)))。但是,在需要更新数据的时候就麻烦了,往中间插入一个记录就必须得挪动后面所有的记录,成本太高。

有序数组索引只适用于静态存储引擎

搜索树:他的特点是:父节点左子树所有结点的值小于父节点的值,右子树所有结点的值大于父节点的值,树可以是二叉树也可以是多叉树。

使用搜索树其实能够保证数据按照键的顺序进行存储,也就是相邻的所有数据其实都是按照自然顺序排列的;

B 树和 B+ 树在数据结构上其实有一些类似,它们都可以按照某些顺序对索引中的内容进行遍历,对于排序和范围查询等操作,B 树和 B+ 树相比于哈希会带来更好的性能

B 树和 B+ 树相比,哈希作为底层的数据结构的表能够以 O(1) 的速度处理单个数据行的增删改查,但是面对范围查询或者排序时就会导致全表扫描的结果,而 B 树和 B+ 树虽然在单数据行的增删查改上需要 O(log n) 的时间,但是它会将索引列相近的数据按顺序存储,所以能够避免全表扫描。

总结:

使用B+树而不是B数的原因

B+树节点大小更小,一次IO读入的节点数更多

B+树的数据都在叶子节点中,遍历和区间访问性能大幅提高

B+树查询效率稳定

使用B+树而不是AVL树、红黑树的原因

B+树的树高比AVL树、红黑树低,IO次数少

所以MySQL选择了B+Tree

对于InnoDB的哈希索引,确切的应该这么说:

(1)InnoDB用户无法手动创建哈希索引,这一层上说,InnoDB确实不支持哈希索引;

(2)InnoDB会自调优(self-tuning),如果判定建立自适应哈希索引(Adaptive Hash Index, AHI),能够提升查询效率,InnoDB自己会建立相关哈希索引,这一层上说,InnoDB又是支持哈希索引的;

2. 索引类型

索引分类

普通索引index :加速查找

唯一索引

主键索引:primary key :加速查找+约束(不为空且唯一)

唯一索引:unique:加速查找+约束 (唯一)

联合索引

-primary key(id,name):联合主键索引

-unique(id,name):联合唯一索引

-index(id,name):联合普通索引

全文索引fulltext :用于搜索很长一篇文章的时候,效果最好。

3. 使用原则

3.1 创建原则

对于经常查询的字段,且区分度大的字段,建议创建索引。

索引不是越多越好,一个表如果有大量索引,不仅占用磁盘空间,而且当表里数据有所更改,维护索引成本较大,且影响增、删、改的效率

避免对经常更新的表进行过多的索引,因为当表中数据更改的同时,索引也会进行调整和更新,十分消耗系统资源。

数据量小的表不需要创建索引,数据量小时索引不仅起不到明显的优化效果,对于索引结构的维护反而消耗系统资源。

不要在区分度低的字段建立索引。比如布尔字段,只有 “失效” 和 “有效” ,建索引完全起不到优化效果。

在频繁进行跑排列分组(即进行 group by 或 order by操作)的列上建立索引,如果待排序有多个,可以在这些列上建立组合索引

区分度公式:

count(distinct(column_name)) / count(*) -- 列的全部不同值个数/所有数据行行

3.2 联合索引的最左匹配原则

当B+Tree的数据项是复合的数据结构,比如(name,age,sex)的时候。

B+Tree是按照从左到右的顺序来建立搜索树的,比如当(张三,20,F)这样的数据来检索的时候,+Tree会优先比较name来确定下一步的所搜方向,如果name相同再依次比较age和sex,最后得到检索的数据;

但当(20,F)这样的没有name的数据来的时候,b+树就不知道下一步该查哪个节点,因为建立搜索树的时候name就是第一个比较因子,必须要先根据name来搜索才能知道下一步去哪里查询。

比如当(张三,F)这样的数据来检索时,b+树可以用name来指定搜索方向,但下一个字段age的缺失,所以只能把名字等于张三的数据都找到,然后再匹配性别是F的数据了, 这个是非常重要的性质,即索引的最左匹配特性。

4.有关索引的几个概念

回表: 如果语句是 select * from T where k=5(k含有索引字段),即普通索引查询方式,则需要先搜索 k 索引树,得到 ID 的值为 500,再到 ID 索引树搜索一次。这个过程回表。

覆盖索引:如果语句是 select k from T where k=5(k含有索引字段),即普通索引查询方式,则需要先搜索 k 索引树,这个称为覆盖索引(执行计划extra 字段为 Using index)。

索引合并:对多个索引分别进行条件扫描,然后将它们各自的结果进行合并(intersect/union),当时and 关系的时候进行intersect操作,or关系的时候进行union操作。5.1版本以后才有的索引合并

索引下推:索引下推(index condition pushdown )简称ICP,是指当进行查询的时候,可以在索引遍历过程中,对索引中包含的字段先做判断,直接过滤掉不满足条件的记录,减少回表次数(执行计划extra 字段为 Using index condition)。5.6版本以后才有的索引下推

以联合索引(name, age)为例。如果现在有一个需求:检索出表中“名字第一个字是张,而且年龄是 10 岁的所有男孩”。

select * from tuser where name like '张%' and age=10 and ismale=1;

5.6版本以前,只是进行匹配查询:

da2310ac7bb1

image.png

5.6版本以后,索引下推:

da2310ac7bb1

image.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值