告别慢查询,解密MySQL慢SQL分析定位

2024-04-19 20:02:09 浏览数 (1)

概述

在业务型java项目中最大的隐患项之一就是慢SQL,它影响到服务的稳定性,也是日常工作中经常导致程序的最大隐患,在日常开发中如何避免出现慢SQL,出现了慢SQL应该按照什么思路去解决是我们必须要知道。其优化原则,总体可以归纳为:

  • 科学创建索引
  • 减少不必要的列查询
  • 使用覆盖索引
  • 语句改写
  • 适当的应用内存进行条件组合分次查询
  • 选择合适的列进行排序
  • 适当的列冗余,减少关联表
  • SQL 拆分,化繁为简
  • 适当结合 ES

问题分析

1. 编写sql 在日常开发中,难免会遇到一些复杂的业务场景需要使用一些复杂的sql来解决业务问题,这些sql往往包含了一些复杂的函数、子查询。在项目的初期由于数据量少,不会对数据库造成太大的压力,但慢慢的随着业务的发展和时间的积累这些sql就会渐渐的成为慢sql,对数据库性能产生一定的影响,甚至影响程序正常运行。

对于这种场景,建议开发人员先了解业务场景,梳理清楚其关联关系,把sql拆分成简单的小sql,对应的关联主键加上索引,在内存中关联组合分次查询。同时在单测时,应用增加大数据量场景验证其性能。

2. 使用explain分析sql 通过 explain 可以初步定位出 SQL 是否使用索引,使用的索引是否正确,排序是否合理、索引列区分度等情况,通过这些基本就可以定位出绝大部分问题。在使用explain进行sql 分析时,我们最需关注的是以下这几个指标:

  • type
  • possible_keys
  • key
  • rows
  • extra

2.1 type type 为索引连接类型,它有下面几种类型的取值,

  • system:该表只有一行(相当于系统表),system 是 const 类型的特例
  • const:针对主键或唯一索引的等值查询扫描,最多只返回一行数据. const 查询速度非常快,因为它仅仅读取一次即可
  • eq_ref:当使用了索引的全部组成部分,并且索引是 PRIMARY KEY 或 UNIQUE NOT NULL 才会使用该类型,性能仅次于 system 及 const。
  • ref:当满足索引的最左前缀规则,或者索引不是主键也不是唯一索引时才会发生。如果使用的索引只会匹配到少量的行,性能也是不错的。
  • range:范围扫描,表示检索了指定范围的行,主要用于有限制的索引扫描。比较常见的范围扫描是带有 BETWEEN 子句或 WHERE 子句里有 >、>=、<、<=、IS NULL、<=>、BETWEEN、LIKE、IN () 等操作符。
  • index:全索引扫描,和 ALL 类似,只不过 index 是全盘扫描了索引的数据。
  • all:全表扫描,性能最差。

对于这几种类型,性能的好坏排序为:system>const>eq_ref>ref>range>index>ALL

2.2 possible_keys 展示当前查询可以使用哪些索引,这一列的数据是在优化过程的早期创建的,因此有些索引可能对于后续优化过程是没用的。

2.3 key 表示 MySQL 实际选择的索引,重点需要注意 Using filesort 和 Using temporary,前者代表无法利用索引完成排序操作,数据较少时从内存排序,否则从磁盘排序,后者 MySQL 需要创建一个临时表来保存结果。

2.4 rows 表示sql所查询的行数

2.5 extra 该列显示 MySQL 在查询过程中的一些详细信息。主要包括:

  • Using filesort
  • Using temporary
  • Using index
  • Using where
  • Using join buffer
  • impossible where
  • select tables optimized away
  • distinct 在日常问题排查中,我们最需要关注 Using filesort、Using temporary、Using index 这几个指标。

0 人点赞