mysql show profile 性能分析工具

mysql profile使用场景及方法

今天有客户反馈,同样的SQL和同样数据量的数据库在RDS和自建库上面,执行时间差异非常大,需要排查一下具体的原因,当时用了show profile给客户说明了具体时间花费在哪一步。首先当然看下具体情况、数据量、索引、执行计划等是否真的如客户所说完全一致,当然这不在我们这篇文档的范围内。

今天我们主要来讲一下mysql show profile查看SQL执行的时间到底去哪了。

准备工作

相关参数:
[profiling] 控制是否开启profiling,值为bool,默认为off。
[profiling_history_size] 控制保存的statement数量,默认为15,上限100,设置为0时关闭profiling。

语法:
SHOW PROFILE [type [, type] ... ]
[FOR QUERY n]
[LIMIT row_count [OFFSET offset]]
type: {
ALL
| BLOCK IO
| CONTEXT SWITCHES
| CPU
| IPC
| MEMORY
| PAGE FAULTS
| SOURCE
| SWAPS
}

使用profile之前,我们先要开启profiling,默认该参数是关闭的,我们可以会话级别设置开启来进行临时测试。

mysql> show variables like 'profiling';
Variable_name Value
profiling OFF

1 row in set (0.00 sec)
mysql> set session profiling = 1;

执行SQL:
select * from class_a_score where id = 1;

mysql> show variables like 'profiling_history_size';
Variable_name Value
profiling_history_size 15

SHOW profiles 结果:show profiles 是查看所有在history size(当前为15)的语句执行花费的时间和具体SQL语句。

mysql> show profiles;
Query_ID Duration Query
1 0.00034000 explain select * from class_a_score where id = 1
2 0.00304225 show variables like 'profiling_history_size'

指定上面SQL_ID,查看具体的query,每个阶段所花费的时间。(注意,show profile只显示上一条SQL的结果)
这里的status,就是show processlist中类似的结果。[可以另外加limit 和 offset 来控制输出内容]

mysql> show profile for query 1;
Status Duration
starting 0.000069
checking permissions 0.000011
Opening tables 0.000018
init 0.000027
System lock 0.000010
optimizing 0.000011
statistics 0.000041
preparing 0.000042
explaining 0.000041
end 0.000005
query end 0.000008
closing tables 0.000014
freeing items 0.000038
cleaning up 0.000005

14 rows in set, 1 warning (0.01 sec)

mysql> show profile for query 1 limit 1;
Status Duration
starting 0.000069

1 row in set, 1 warning (0.01 sec)

mysql> show profile for query 1 limit 1 offset 2;
Status Duration
Opening tables 0.000018

1 row in set, 1 warning (0.01 sec)

show profile 进阶

另外可以加上type 查看具体花费在CPU还是读写数据上等。

mysql> show profile cpu;
Status Duration CPU_user CPU_system
starting 0.000065 0.000000 0.000053
checking permissions 0.000011 0.000000 0.000010
Opening tables 0.000019 0.000000 0.000018
init 0.000016 0.000000 0.000016
System lock 0.000010 0.000000 0.000010
optimizing 0.000006 0.000000 0.000006
statistics 0.000010 0.000000 0.000009
preparing 0.000009 0.000000 0.000009
executing 0.000005 0.000000 0.000005
Sending data 0.000482 0.000000 0.000483
end 0.000006 0.000000 0.000005
query end 0.000008 0.000000 0.000009
closing tables 0.000008 0.000000 0.000008
freeing items 0.000051 0.000000 0.000060
cleaning up 0.000014 0.000000 0.000005

15 rows in set, 1 warning (0.01 sec)
mysql show profile 性能分析工具
这个就是因为时间都花费在物理读上面,导致执行时间过长。

在performance_schema中的应用

因为官方文档中指出,可能再不久将来会废除show profile(因为确实有局限性,比如只能在当前会话使用),目前已经支持使用performance_schema来查看,如下是开启过程:

1、查看是否需要限制哪些前端线程会被记录
SELECT * FROM performance_schema.setup_actors;
INSERT INTO performance_schema.setup_actors
(HOST,USER,ROLE,ENABLED,HISTORY)
VALUES('localhost','test_user','%','YES','YES');

2、开启统计timer和eventUPDATE performance_schema.setup_instruments
SET ENABLED = 'YES', TIMED = 'YES'
WHERE (NAME LIKE '%statement/%' or NAME LIKE '%stage/%');

UPDATE performance_schema.setup_consumers
SET ENABLED = 'YES'
WHERE (NAME LIKE '%events_statements_%' or NAME LIKE '%events_stages_%');

3.查找出来event_id
SELECT EVENT_ID, TRUNCATE(TIMER_WAIT/1000000000000,6) as Duration, SQL_TEXT
FROM performance_schema.events_statements_history_long WHERE SQL_TEXT like '%sql_text%'

4.把上一步查出来event_id带入
SELECT event_name AS Stage, TRUNCATE(TIMER_WAIT/1000000000000,6) AS Duration

FROM performance_schema.events_stages_history_long WHERE NESTING_EVENT_ID=<?>;

查考:
https://dev.mysql.com/doc/refman/5.6/en/show-profile.html

上一篇:高性能 Java 网络框架 Apache MINA 2.0.14


下一篇:《Hadoop MapReduce性能优化》一2.4 用Apache Ambari监测Hadoop