【MySQL】MySQL优化原则

1、小表驱动大表

这条优化原则要求查询中按执行顺序尽量用小数据集驱动大数据集。
示例1:

在使用in条件时,先执行in条件子句,此时由于B表先查,A表后查,B表的数据集应小于A表的数据集。

B表数据集小于A表数据集时,用in优于exists。

示例2:

在使用exists条件时,先执行外层的查询,此时由于A表先查,B表后查,A表的数据集应小于B表的数据集。

A表数据集小于B表数据集时,用exists优于in。

注意:A表和B表的id字段都应建索引

exists:将主查询的数据放到子查询中做条件验证,根据验证结果来决定主查询的数据是否保留。

  • 由于exists子句只返回true或false,因此子查询中select后可以是任意字段或常量,实际执行时会忽略select清单,没有区别。
  • exists子查询常常也能用条件表达式、其他子查询或是join来替代,何种情况最优要根据具体业务情况进行分析(explain命令和日志)

2、order by排序优化

order by子句应尽量使用index方式排序,避免使用filesort方式排序。因为index方式排序效率高,而filesort存在文件内排序,降低了执行效率。
order by子句使用index方式排序需要满足以下条件之一:

  • order by 子句使用索引左前列
  • 使用where子句和order by子句的条件列组合满足索引的左前列原则

因此尽可能在索引列上完成排序操作,并遵循索引的左前列原则。



再来看看filesort流程:

从磁盘读取查询需要的所有列,按照order by列在buffer中对进行排序,然后扫描排序后的列表进行输出。避免了二次读取数据,并把随机IO变成了顺序IO。

这个流程引出了一个问题:

filesort需要一次性将所有排序字段都取出,如果超过了sort_buffer的容量,导致每次只能取出该容量的数据,通过创建tmp文件、多路合并的方式来排序,将大大增加IO次数,导致性能急剧下降。

因此要根据实际情况调整sort_buffer_size和max_length_for_sort_data参数,避免出现上述情况。

3、group by分组优化

group by实质上是先排序再分组,因此也遵循索引的左前缀原则,其索引失效情况和order by保持一致。
需要注意的是group by还有一个having子句作为分组后的条件,由于where子句先于having执行,因此能在where中限定的条件不要放在having中

4、避免索引失效导致行锁变表锁

众所周知InnoDB存储引擎是支持行锁的,适合高并发场景,但由于MySQL的行锁是通过索引实现的,即行锁是通过给索引项加锁来实现的,只有通过索引条件查找数据,InnoDB才使用行级锁,否则将使用表锁。因此当索引失效时,行锁会变成表锁导致性能下降。

原创文章 10 获赞 10 访问量 4754

猜你喜欢

转载自blog.csdn.net/Steven_L_/article/details/105856676