前言
MySQL慢的诊断思路,一般我会从三个方向来做:
第一个方向是SQL语句本身
- 需求方一定要按照数据库容易接受的方式去写SQL,这个成本会下降的非常快。
- 官当文档中Examples of Common Queries 专门写出常规SQL语句
- 一些示例:
-
去除不必要的括号:
-
恒定折叠:
-
恒定条件去除:
-
第二个方向是MySQL内部的观测
-
第一步直接的方法就是使用 PROCESSLIST
PROCESSLIST 可以直观的来看下目前SQL的压力不太正常。
-
Id
连接标识符。显示的
PROCESSLIST_ID
值。 -
User
声明用户。是
system user
指由服务器生成的用于在内部处理任务的非客户端线程 -
Host
发出语句的客户端的主机名。TCP/IP 连接的主机名以 格式报告, 以便更容易确定哪个客户端在做什么。
-
db
线程的默认数据库,或者
NULL
如果没有选择。 -
Command
线程代表客户端执行的命令类型,或者
Sleep
会话是否空闲。 -
Time
线程处于当前状态的时间(以秒为单位)。
-
State
指示线程正在执行的操作的操作、事件或状态。
Killed、Locked、Sending data、Sleeping、Updating等
大多数状态对应于非常快速的操作。如果一个线程在给定状态下停留了很多秒,则可能存在需要调查的问题。
-
Info
线程正在执行的语句。
-
-
第二步是 EXPLAIN ,模拟优化器执行SQL执行计划
在日常工作中,我们常常用到
EXPLAIN
这个命令来查看一个这些 SQL 语句的执行计划,查看该 SQL 语句有没有使用上了索引,有没有全表扫描,这都可以通过EXPLAIN
命令来查看。所以我们通过使用EXPLAIN
获得很多可能被优化器考虑到的访问策略的细节,以及当运行 SQL 语句时哪种策略预计会被优化器采用。当
EXPLAIN
与可解释语句【SELECT
,DELETE
,INSERT
,REPLACE
,UPDATE
】一起使用时,MySQL 会显示来自优化器的有关语句执行计划的信息。也就是说,MySQL 解释了它将如何处理语句,包括有关如何连接表和按什么顺序连接的信息。有关EXPLAIN
用于获取执行计划信息的信息。
EXPLAIN 中重要字段的参数非常多,准备单拿出一篇来讲解 EXPLAIN ,以帮助选择更好的索引和写出更优化的查询语句。 -
第三步要做Profilling。
若这个SQL能再执行一次的话, 就做一个Profilling。
profiling,用于诊断一条sql在执行过程中的资源消耗情况,可以通过profiling来查看慢sql到底慢在哪里,从而进行合理的优化。
第三个方向是外部资源的观测
- 机器的平均负载,有无异常,IO是否正常
- 内存状态,页的换进换出有没有什么问题,内存使用率
- CPU的压力是否均匀
- 进程资源占用
- 目前进程和线程的状态