mysql索引失效和优化

一、单表索引优化

1.1 全值匹配

查询的条件字段按照顺序在索引中都可以匹配到

CREATE INDEX idx_age_deptid_name ON emp(age,deptid,NAME);

在这里插入图片描述

1.2 最佳左前缀法则

使用复合索引, 需要遵循最佳左前缀法则, 即如果索引了多列, 要遵守最左前缀法则。 指的是查询从索引的最左前列开始并且不跳过索引中的列。
过滤条件要使用索引必须按照索引建立时的顺序, 依次满足, 一旦跳过某个字段, 索引后面的字段都无法被使用。
在这里插入图片描述

1.3 不要在索引列上做任何计算

计算、 函数、 (自动 or 手动)类型转换,会导致索引失效而转向全表扫描。
在这里插入图片描述

1.4 索引列上不能有范围查询

将可能做范围查询的字段的索引顺序放在最后
在这里插入图片描述

1.5 尽量使用覆盖索引

即查询列和索引列一致, 不要写 select *
在这里插入图片描述

1.6 使用不等于(!= 或者<>)

有时会无法使用索引会导致全表扫描
在这里插入图片描述

1.7 字段的is not null 用不到索引 ,is null可以用到索引

当字段允许为null时:
在这里插入图片描述
is not null 用不到索引, is null 可以用到索引。

1.8 like 的前后模糊匹配

前缀不能出现模糊匹配否则索引失效
在这里插入图片描述

在这里插入图片描述

解决 like ‘%字符串%’时索引失效的方法:
使用覆盖索引, 既查询列和索引列一致

1.9 字符串加单引号

导致索引列上自动计算导致索引失效
在这里插入图片描述

1.10 减少使用 or

or可能导致索引失效尽量使用 union all 或者 union 来替代
在这里插入图片描述
在这里插入图片描述

二、关联查询优化

能够直接多表关联的尽量直接关联, 不用子查询!
小表驱动大表原则

2.1 left join

在优化关联查询时, 只有在被驱动表上建立索引才有效!
left join 时, 左侧的为驱动表, 右侧为被驱动表!
left join时, 尽量让实体表作为被驱动表。

2.2 inner join

inner join 时, mysql 会自己帮你把小结果集的表选为驱动表。
子查询尽量不要放在被驱动表, 有可能使用不到索引;

三、子查询优化

在范围判断时, 尽量不要使用 not in 和 not exists, 使用 left join on xxx is null 代替。
在这里插入图片描述
解决 dept 表的全表扫描, 建立 ceo 字段的索引
在这里插入图片描述

四、排序分组优化

4.1 无过滤不索引

无过滤, 不索引。 where, limt 都相当于一种过滤条件, 所以才能使用上索引!
在这里插入图片描述
在这里插入图片描述
using filesort 说明进行了手工排序 原因在于没有 where 作为过滤条件
在这里插入图片描述

4.2 顺序错, 必排序

where 两侧列的顺序可以变换, 效果相同, 但是 order by 列的顺序不能随便变换
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4.3 方向反, 必排序

如果排序的字段, 顺序有差异, 就需要将差异的部分, 进行一次倒置顺序, 因此还是需要手动排序的
在这里插入图片描述
在这里插入图片描述

4.4 索引的选择

当范围条件和 group by 或者 order by 的字段出现二选一时 , 优先观察条件字段的过滤数量, 如果过滤的数据足够多, 而需要排序的数据并不多时, 优先把索引放在范围字段上。 反之, 亦然。

4.5 using filesort

mysql 的排序算法:

双路排序
MySQL 4.1 之前是使用双路排序,字面意思就是两次扫描磁盘, 最终得到数据, 读取行指针和 orderby 列, 对他
们进行排序, 然后扫描已经排序好的列表, 按照列表中的值重新从列表中读取对应的数据输出。
从磁盘取排序字段, 在 buffer 进行排序, 再从磁盘取其他字段。
简单来说, 取一批数据, 要对磁盘进行了两次扫描, 众所周知, I\O 是很耗时的, 所以在 mysql4.1 之后, 出现了第二种改进的算法, 就是单路排序。

单路排序
从磁盘读取查询需要的所有列, 按照 order by 列在 buffer 对它们进行排序, 然后扫描排序后的列表进行输出,它的效率更快一些, 避免了第二次读取数据。 并且把随机 IO 变成了顺序 IO,但是它会使用更多的空间,因为它把每一行都保存在内存中了。

优化方法:

  • 增大 sort_butter_size 参数的设置
  • 增大 max_length_for_sort_data 参数的设置
  • 减少 select 后面的查询的字段。

4.6 使用覆盖索引

SQL 只需要通过索引就可以返回查询所需要的数据, 而不必通过二级索引查到主键之后再去查询数据
在这里插入图片描述

4.7 group by

group by 使用索引的原则几乎跟 order by 一致 , 唯一区别是 groupby 即使没有过滤条件用到索引, 也可以直接使用索引
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值