1.索引失效的几种情况
1.1 全值匹配我最爱
1.2 最佳左前缀法则
1.3 主键插入顺序,主键不是递增,可能造成页分裂、性能损耗
1.4 计算、函数、类型转换(自动或手动)导致索引失效
1.5 类型转换导致索引失效
1.6 范围条件右边的列索引失效
CREATE INDEX idx_age_classId_name on student(age,classId,NAME);
EXPLAIN SELECT SOL NO CACHE * FRoM studentWHERE student,age=30 AND student.classId>20 AND student.name = ‘abc’ ;
因为classid 使用了范围条件,导致name索引没用上。
1.7 不等于(!= 或者<>)索引失效
1.8 is null可以使用索引,is not null无法使用索引
1.9 like以通配符%开头索引失效
1.10 OR前后存在非索引的列,索引失效
1.11 数据库和表的字符集统一使用utf8mb4
不同的字符集进行比较前需要转换,会造成索引失效。
2.关联查询优化
2.1、整体效率比较:INLJ>BNLJ>SNLJ
2.2 、永远用小结果集驱动大结果集(其本质就是减少外层循环的数据数量)(小的度量单位指的是 表行数"每行大小
2.3 、为被驱动表匹配的条件增加索引(减少内层表的循环匹配次数)
2.4 、增大join buffer size的大小(一次缓存的数据越多,那么内层包的扫表次数就越少)
2.5 、减少驱动表不必要的字段査询(字段越少,join buffer 所缓存的数据就越多)
两个结论:
对于内连接来说,查询优化器可以决定谁作为驱动表,谁作为被驱动表出现的
对于内连接来讲,如果表的连接条件中只能有一个字段有索引,则有索引的字段所在的表会被作为被驱动表
3.JOIN语句原理
3.1、Simple Nested -Loop Join(简单嵌套循环连接)
类似于java程序中双重嵌套循环一样
3.2、Index Nested-Loop Join(索引嵌套循环连接)
连接条件使用到了索引
3.3、Block Nested-Loop Join(块嵌套循环连接)
不再是逐条获取驱动表的数据,而是一块一块的获取,引入了join buffer缓冲区,将驱动表join相关的部分数据列(大小受ioin bufer的限制)缓存到ioin bufer中,然后全表扫描被驱动表,被驱动表的每一条记录一次性和joinbuffer中的所有驱动表记录进行匹配(内存中操作),将简单嵌套循环中的多次比较合并成一次,降低了被驱动表的访问频率。单条数据匹配变成批量匹配。