转自:http://www.percona.com/blog/2015/04/16/profiling-mysql-queries-from-performance-schema/

When optimizing queries and investigating performance issues, MySQL comes with built in support for profiling queries aka SET profiling = 1; . This is already awesome and simple to use, but why the PERFORMANCE_SCHEMA alternative?

Because profiling will be removed soon (already deprecated on MySQL 5.6 ad 5.7); the built-in profiling capability can only be enabled per session. This means that you cannot capture profiling information for queries running from other connections. If you are using Percona Server, the profiling option for log_slow_verbosity is a nice alternative, unfortunately, not everyone is using Percona Server.

Now, for a quick demo: I execute a simple query and profile it below. Note that all of these commands are executed from a single session to my test instance.

mysql> SHOW PROFILES;
+----------+------------+----------------------------------------+
| Query_ID | Duration | Query |
+----------+------------+----------------------------------------+
| 1 | 0.00011150 | SELECT * FROM sysbench.sbtest1 LIMIT 1 |
+----------+------------+----------------------------------------+
1 row in set, 1 warning (0.00 sec)
mysql> SHOW PROFILE SOURCE FOR QUERY 1;
+----------------------+----------+-----------------------+------------------+-------------+
| Status | Duration | Source_function | Source_file | Source_line |
+----------------------+----------+-----------------------+------------------+-------------+
| starting | 0.000017 | NULL | NULL | NULL |
| checking permissions | 0.000003 | check_access | sql_parse.cc | 5797 |
| Opening tables | 0.000021 | open_tables | sql_base.cc | 5156 |
| init | 0.000009 | mysql_prepare_select | sql_select.cc | 1050 |
| System lock | 0.000005 | mysql_lock_tables | lock.cc | 306 |
| optimizing | 0.000002 | optimize | sql_optimizer.cc | 138 |
| statistics | 0.000006 | optimize | sql_optimizer.cc | 381 |
| preparing | 0.000005 | optimize | sql_optimizer.cc | 504 |
| executing | 0.000001 | exec | sql_executor.cc | 110 |
| Sending data | 0.000025 | exec | sql_executor.cc | 190 |
| end | 0.000002 | mysql_execute_select | sql_select.cc | 1105 |
| query end | 0.000003 | mysql_execute_command | sql_parse.cc | 5465 |
| closing tables | 0.000004 | mysql_execute_command | sql_parse.cc | 5544 |
| freeing items | 0.000005 | mysql_parse | sql_parse.cc | 6969 |
| cleaning up | 0.000006 | dispatch_command | sql_parse.cc | 1874 |
+----------------------+----------+-----------------------+------------------+-------------+
15 rows in set, 1 warning (0.00 sec)

To demonstrate how we can achieve the same with Performance Schema, we first identify our current connection id. In the real world, you might want to get the connection/processlist id of the thread you want to watch i.e. from SHOW PROCESSLIST .

mysql> SELECT THREAD_ID INTO @my_thread_id
-> FROM threads WHERE PROCESSLIST_ID = CONNECTION_ID();
Query OK, 1 row affected (0.00 sec)

Next, we identify the bounding EVENT_IDs for the statement stages. We will look for the statement we wanted to profile using the query below from the events_statements_history_long table. Your LIMIT clause may vary depending on how much queries the server might be getting.

mysql> SELECT THREAD_ID, EVENT_ID, END_EVENT_ID, SQL_TEXT, NESTING_EVENT_ID
-> FROM events_statements_history_long
-> WHERE THREAD_ID = @my_thread_id
-> AND EVENT_NAME = 'statement/sql/select'
-> ORDER BY EVENT_ID DESC LIMIT 3 G
*************************** 1. row ***************************
THREAD_ID: 13848
EVENT_ID: 419
END_EVENT_ID: 434
SQL_TEXT: SELECT THREAD_ID INTO @my_thread_id
FROM threads WHERE PROCESSLIST_ID = CONNECTION_ID()
NESTING_EVENT_ID: NULL
*************************** 2. row ***************************
THREAD_ID: 13848
EVENT_ID: 374
END_EVENT_ID: 392
SQL_TEXT: SELECT * FROM sysbench.sbtest1 LIMIT 1
NESTING_EVENT_ID: NULL
*************************** 3. row ***************************
THREAD_ID: 13848
EVENT_ID: 353
END_EVENT_ID: 364
SQL_TEXT: select @@version_comment limit 1
NESTING_EVENT_ID: NULL
3 rows in set (0.02 sec)

From the results above, we are mostly interested with the EVENT_ID and END_EVENT_ID values from the second row, this will give us the stage events of this particular query from the events_stages_history_long table.

mysql> SELECT EVENT_NAME, SOURCE, (TIMER_END-TIMER_START)/1000000000 as 'DURATION (ms)'
-> FROM events_stages_history_long
-> WHERE THREAD_ID = @my_thread_id AND EVENT_ID BETWEEN 374 AND 392;
+--------------------------------+----------------------+---------------+
| EVENT_NAME | SOURCE | DURATION (ms) |
+--------------------------------+----------------------+---------------+
| stage/sql/init | mysqld.cc:998 | 0.0214 |
| stage/sql/checking permissions | sql_parse.cc:5797 | 0.0023 |
| stage/sql/Opening tables | sql_base.cc:5156 | 0.0205 |
| stage/sql/init | sql_select.cc:1050 | 0.0089 |
| stage/sql/System lock | lock.cc:306 | 0.0047 |
| stage/sql/optimizing | sql_optimizer.cc:138 | 0.0016 |
| stage/sql/statistics | sql_optimizer.cc:381 | 0.0058 |
| stage/sql/preparing | sql_optimizer.cc:504 | 0.0044 |
| stage/sql/executing | sql_executor.cc:110 | 0.0008 |
| stage/sql/Sending data | sql_executor.cc:190 | 0.0251 |
| stage/sql/end | sql_select.cc:1105 | 0.0017 |
| stage/sql/query end | sql_parse.cc:5465 | 0.0031 |
| stage/sql/closing tables | sql_parse.cc:5544 | 0.0037 |
| stage/sql/freeing items | sql_parse.cc:6969 | 0.0056 |
| stage/sql/cleaning up | sql_parse.cc:1874 | 0.0006 |
+--------------------------------+----------------------+---------------+
15 rows in set (0.01 sec)

As you can see the results are pretty close, not exactly the same but close. SHOW PROFILE shows Duration in seconds, while the results above is in milliseconds.

Some limitations to this method though:

  • As we’ve seen it takes a few hoops to dish out the information we need. Because we have to identify the statement we have to profile manually, this procedure may not be easy to port into tools like the sys schema or pstop.
  • Only possible if Performance Schema is enabled (by default its enabled since MySQL 5.6.6, yay!)
  • Does not cover all metrics compared to the native profiling i.e. CONTEXT SWITCHES, BLOCK IO, SWAPS
  • Depending on how busy the server you are running the tests, the sizes of the history tables may be too small, as such you either have to increase or loose the history to early i.e. performance_schema_events_stages_history_long_size variable. Using ps_history might help in this case though with a little modification to the queries.
  • The resulting Duration per event may vary, I would think this may be due to the additional as described on performance_timers table. In any case we hope to get this cleared up as result when this bug is fixed.

Profiling MySQL queries from Performance Schema的更多相关文章

  1. MySQL 5.7 Performance Schema 详解

    refman mysql 5.7 MySQL Performance Schema  用于监视MySQL服务器,且运行时消耗很少的性能.Performance Schema 收集数据库服务器性能参数, ...

  2. [MySQL Reference Manual] 23 Performance Schema结构

    23 MySQL Performance Schema 23 MySQL Performance Schema 23.1 性能框架快速启动 23.2 性能框架配置 23.2.1 性能框架编译时配置 2 ...

  3. Mysql之performance Schema

    Performance schema是用于监控Mysql执行,具有如下特征: 1.用于在运行时探查Mysql Server的执行过程,是由Performance_schema引擎和 Performan ...

  4. MySQL调优性能监控之performance schema

    一.performance_schema的介绍 performance:性能 schema:图(表)示,以大纲或模型的形式表示计划或理论. MySQL的performance schema 用于监控M ...

  5. MySQL Performance Schema详解

    MySQL的performance schema 用于监控MySQL server在一个较低级别的运行过程中的资源消耗.资源等待等情况. 1 performance schema特点 提供了一种在数据 ...

  6. 通过performance schema收集慢查询

    MySQL5.6起performance schema自动开启,里面涉及记录 statement event的表 mysql> show tables like '%statement%'; + ...

  7. mysql performance schema的即时诊断工具-邱伟胜

    https://github.com/noodba http://www.noodba.com

  8. 【MySQL】MySQL 5.7 sys Schema

    sys库说明:http://dev.mysql.com/doc/refman/5.7/en/sys-schema-usage.html sys库使用说明:http://dev.mysql.com/do ...

  9. MySql(九):MySQL性能调优——Schema设计的性能优化

    一.高效的模型设计 先了解下数据库设计的三大范式 第一范式:要求有主键,并且要求每一个字段原子性不可再分 第二范式:要求所有非主键字段完全依赖主键,不能产生部分依赖 第三范式:所有非主键字段和主键字段 ...

随机推荐

  1. UNIQUEIDENTIFIER列上的统计信息

    UNIQUEIDENTIFIER列上的统计信息非常有意思,在它上面有一些很令人讨厌的行为.我们来看下. 问题重现(The repro) 为了向你展示我们刚抱怨的行为,我用下列简单的表定义创建了一个数据 ...

  2. mysql-5.6.14-winx64免安装配置

    MySQL5.6.11安装步骤(Windows7 64位) 1. 下载MySQL Community Server 5.6.14 2. 解压MySQL压缩包 将以下载的MySQL压缩包解压到自定义目录 ...

  3. [JS] JavaScript由浅入深(2) 进阶

    本节,将围绕以下几点来讲. 知识点:多线程.作用域.闭包.this 先顶后看 1.多线程 在不支持H5的浏览器中.使用Concurrent.Thread.js. 在支持H5中,使用WebWork. 在 ...

  4. 投票系统 & 简易js刷票脚本

    早就听说有什么刷票脚本,微博投票等等相关的投票都有某些人去刷票. 试一下吧,兴许自己也会刷票呢?捣鼓了几个小时,终于有所眉目. (1)投票系统 要刷票,就得先有个投票界面. 当然,可以直接去各个投票网 ...

  5. DFS --- HNU 13307 Galaxy collision

    Galaxy collision Problem's Link Mean: 给定二维坐标平面内的n个整数点,让你把这n个点划分为两个集合,同一集合内的所有点必须两两距离大于5,求这两个集合的元素个数之 ...

  6. Winform调用QQ发信息并且开机启动 (开源)

    前言 公司CS系统需要加入启动qq从winform调用qq聊天窗口的功能,前提是需要将聊天者的QQ号码作为参数传递到函数中,一直没有搞过,正好很感兴趣,就折腾,Winform调用qq,我想肯定是需要一 ...

  7. Visual Studio中设置默认VC++路径

    菜单"View" -> "Other Windows" -> "Property Manager" 选择对应的配置并修改即可.

  8. CentOS7.2设置zabbix

    准备工作 1.lnmp或lamp环境,本机环境:CentOS 7.2 64位,nginx1.10.2 php5.6.26 mysql5.7.15 2.软件Zabbix wget http://nchc ...

  9. WinJs项目介绍

        WinJs库是最近微软公布的一个开源项目.它与开源社区的协作共同完成.为了轻易创建HTML/JS/CSS应用程序开发的解决方案.WinJS是一个Javascripts的工具箱让开发人员使用HT ...

  10. mysql performance_schema/information_schema授权问题

    mysql> grant all on performance_schema.* to 'testuser'@'%';ERROR 1044 (42000): Access denied for ...