1.1. MySql如何定位慢查询与分析解决

1.1.1. 定位慢查询

慢查询概念:测压时耗时超过一定时间的接口,主要是由于数据库查询速度过慢导致,在以下查询中比较经常出现慢查询的情况

主要有两个方案可以对慢查询进行定位

第一个方案是下载第三方工具:比如Arthas,Prometheus

第二方案是使用MySql自带的慢查询日志。一般推荐第一个方案,因为MySql自带的慢查询日志对MySql性能有一定的影响,而且Arthas可以监听到很多,比如JVM内存情况等,不只是适用于这里,有兴趣的自己看链接学习一下

Java 线上问题排查神器 Arthas 快速上手与原理浅谈-阿里云开发者社区 (aliyun.com)

第二个方案进行慢查询定位主要是根据MySql的三个配置属性实现的

  • long_query_time :10.000000:查询超过10秒被定义为慢语句(这个参数可以根据业务接口的重要性以及调用频繁性进行合理设置)
  • slow_query_log :OFF:是否打开慢查询日志
  • slow_query_log_file : /usr/local/mysql/data/slow.log:慢查询日志文件所在位置

打开后重启Mysql,进行慢查询文件中去看就可以知道哪个Sql在执行上比较慢

1.1.2. 如何优化慢查询

先关注SQL的执行计划,也就是SQL执行过程中的流程,找到慢的原因

回表查询就是指查询了二级索引,二级索引先根据b+树找到主键,然后根据主键找到了二级索引列的数据,走两次b+树

不需要回表查询,也就是索引本身就是主键索引,直接根据主键找到对应的数据即可,走一次b+树

总结:

  1. 如果慢查询是由于没走索引导致,加索引即可
  2. 如果是因为mysql查询优化器会误使用非预期索引导致语句查询缓慢,这时候需要修改sql逻辑引导优化器使用正确的索引
  3. 如果是数据表太大导致的,那么就要考虑分库实现

一些SQL优化的参考信息

  1. 使用EXISTS代替IN可能会提高性能,但并非所有情况都适用。具体要依据测试结果而定。如果子表很大尽可能使用左连接实现
  2. 使用WHERE 子句替代 HAVING 子句在有些情况下会提高性能。具体根据实际测试而定
  3. 使用NOT EXIST或外连接代替NOT IN可能会提高性能,但并非所有情况都适用。具体要依据测试结果而定。如果子表很大尽可能使用左连接实现。
  4. 000011.1 为保证SQL的执行效率,应避免使用UNION、 OR 子句,可考虑在应用中对结果集进行处理。

前些天公司的某个接口常常出现慢查询的情况,后面根据分析,就是由于数据量日积月累太多以及SQL语句有点问题导致,优化了SQL语句,把Union转为Union All 加上Distinct去除重复数据,将慢查询从4秒降到了3秒以下。

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐