4. 通过 SHOW PROFILE 分析 SQL

MySQL 从 5.0.37 版本开始增加了对 SHOW PROFILES SHOW PROFILE 语句的支持。

通过 have_profiling 参数,能够看到当前 MySQL 是否支持 profile:

mysql> SELECT @@have_profiling;
+------------------+
| @@have_profiling |
+------------------+
| YES              |
+------------------+
1 row in set, 1 warning (0.00 sec)

通过 profiling 参数,可以控制是否启用 profile 功能:

SET PROFILING = 1;
SELECT @@profiling;

-- 设置列表容量大小
SET profiling_history_size := 100;

注意:如果在 datagrip 上使用 profile,如果不设置 profiling_history_size 扩大列表容量,因为 datagrip 增加一些隐式的 sql 调用,因此会非常快速的耗尽列表容量,导致想要分析的目标 SQL 被挤出去,导致 profile 功能无法正常使用!

通过 profile,能够更清楚地了解 SQL 执行的过程。

首先,在一个 innodb 引擎的付款表 payment 上,执行一个 COUNT(*) 查询:

SELECT count(*) FROM payment;
+----------+
| count(*) |
+----------+
|    16044 |
+----------+
1 row in set (0.00 sec)

执行完毕后,通过 SHOW PROFILES 语句,看到当前 SQL 的 Query ID 为 4:

通过 SHOW PROFILE FOR QUERY 语句能够看到执行过程中线程的每个状态和消耗的时间:

Sending data 状态表示 MySQL 线程开始访问数据行并把结果返回给客户端,而不仅仅是返回结果给客户端。由于在 Sending data 状态下,MySQL 线程往往需要做大量的磁盘读取操作,所以经常是整个查询中耗时最长的状态。

为了更清晰地看到排序结果,可以查询 INFORMATION_SCHEMA.PROFILING 表并按照时间做个 DESC 排序:

在获取到最消耗时间的线程状态后,MySQL 支持进一步选择 allcpublock iocontext switchpage faults 等明细类型来查看 MySQL 在使用什么资源上耗费了过高的时间。

最后更新于