文章目录
- 1. 索引失效的案例
- 1.1 最左优先
- 1.2 主键插入顺序
- 1.3 计算、函数、类型转换(自动或手动)导致索引失效
- 1.4 范围条件右边的列索引失效
- 1.5 非 条件索引失效
- 1.6 like以通配符%开头索引失效
- 1.7 OR 前后存在非索引的列,索引失效
- 2. 关联查询优化
1. 索引失效的案例
1.1 最左优先
1.2 主键插入顺序
数据页和记录又是按照记录主键值从小到大的顺序进行排序,所以如果我们插入的记录的主键值是依次增大的话,那我们每插满一个数据页就换到下一个数据页继续插,而如果我们插入的主键值忽小忽大的话,就比较麻烦了,可能会造成页面分裂
和记录移位
- 让主键具有 AUTO_INCREMENT ,让存储引擎自己为表生成主键,而不是我们手动插入
1.3 计算、函数、类型转换(自动或手动)导致索引失效
第一种:对索引字段作用函数,导致索引失效:
第二种 对索引字段计算,导致索引失效:
第三种:类型转换导致索引失效:
1.4 范围条件右边的列索引失效
(age、classId、name)的顺序创建的聚合索引
原因:因为前一个条件相同的情况下 当前条件才会是有序的。
当前一个条件不同 那么无法保证当前条件为有序的 所以索引失效
其实就是二级索引的话,如果都是等值判断的话,那是有序的,先查age,age选出一部分数据后再查classId,classId再筛选一部分后再查name;如果不是等值查询的话,比如说classId使用到了范围,那经过classId范围筛选出一部分数据后,此时对于classId后面的所有索引来说,此时的状态是无序的,关键字不是有序,只能逐个查找,导致索引失效。
1.5 非 条件索引失效
- 不等于(!= 或者<>)索引失效
- is null可以使用索引,is not null无法使用索引(相当于非条件)
1.6 like以通配符%开头索引失效
1.7 OR 前后存在非索引的列,索引失效
or其实就是取并集,两个条件的前面有索引,后面没有索引,但要取并集,还是要扫描全表,导致索引失效。
使用到了索引:而且是两个索引
你能看到这里使用到了 index_merge,简单来说index_merge
就是对age和name分别
进行了扫描,然后将这两个结果集进行了合并
。这样做的好处就是 避免了全表扫描
。
2. 关联查询优化
- 外连接
- 右表是我们的关键点,一定需要建立索引 。
- 内连接
- 对于内连接来说,查询优化器可以决定谁作为驱动表,谁作为被驱动表出现的
- 小表驱动大表
- 被驱动表创建索引
Join语句的原理:
- Simple Nested-Loop Join(索引嵌套循环连接)外表取一个记录,内表都拿过来判断
- Index Nested-Loop Join(索引嵌套循环连接)外表取一个记录,根据拿到的匹配字段走索引,再将索引查出来的进行匹配
- Block Nested-Loop Join(块嵌套循环连接)驱动表批量加载到join buffer中,外表加载一定的次数,进行批量匹配,这个一定次数是基于驱动表分几次可以加载到join buffer中的
Mysql8之后: Hash Join