• mysql5.7全局考虑性能化,SQL优化的最后一步:profile性能分析


    一、JDBC

    setResultSetType(ResultSet.TYPE_FORWARD_ONLY);   告诉mysql发送流数据过来

    setFetchSize(1000);      告诉mysql获取条数

    拿部分数据过来,直到把所有数据都处理完毕。

    用游标也可以。

    但上述用游标或者流的方式,都是把压力都转嫁给了mysql,mysql会开辟一个内存出来去放结果集,对mysql而言,会产生极大的压力。那可以考虑比如手动在java层做分页。

    二、线程繁忙原因

    有时候mysql在执行某SQL时遇上线程繁忙,mysql对于线程状态有细致规定: https://dev.mysql.com/doc/refman/5.7/en/general-thread-states.html 

    【statistics】 统计。线程正在统计信息以研究查询执行计划。如果线程长时间处于这个状态,意味着这个线程可能被别的磁盘IO占用了。

    【Creating tmp table】创建临时表。正在创建一个内存中或磁盘中的临时表,如果刚开始创建的是内存临时表,后来改为创建磁盘临时表,则状态会变为“Coping to tmp table on disk”

    我们可以使用 show processlist;   来查看线程处于什么状态:

    三、profile性能分析

    mysql> select @@have_profiling;   -- 查看是否支持profile
    +------------------+
    | @@have_profiling |
    +------------------+
    | YES              |
    +------------------+
    1 row in set (0.02 sec)

    开启profile:

    mysql> select @@profiling;  -- 如果支持profile的话,那么查看是否开启了profile, 默认是0不开启,可以通过  set profiling=1; 设置为session级别的开启
    +-------------+
    | @@profiling |
    +-------------+
    |           0 |
    +-------------+
    1 row in set (0.02 sec)

    这时候执行一个sql:   SELECT * FROM t_user WHERE address in ('shanghaishi', 'beijingshi', 'wenzhoushi');   结果集大约有8654条数据。再用  show profiles;  命令去看刚才那个SQL的执行耗时情况:

    mysql> show profiles;
    +----------+------------+-----------------------------------------------------------------------------------+
    | Query_ID | Duration   | Query                                                                             |
    +----------+------------+-----------------------------------------------------------------------------------+
    |        1 | 0.00036600 | select @@profiling                                                                |
    |        2 | 0.01598275 | select count(*) from t_user                                                       |
    |        3 | 0.02613600 | SELECT * FROM t_user WHERE address in ('shanghaishi', 'beijingshi', 'wenzhoushi') |
    +----------+------------+-----------------------------------------------------------------------------------+
    3 rows in set (0.05 sec)

    记住这里的Query_ID是3,然后     show profile for query 3;

    mysql> show profile for query 3;
    +----------------------+----------+
    | Status               | Duration |
    +----------------------+----------+
    | starting             | 0.000061 |
    | checking permissions | 0.000010 |
    | checking permissions | 0.000004 |
    | Opening tables       | 0.000018 |
    | init                 | 0.000075 |
    | System lock          | 0.000011 |
    | optimizing           | 0.000014 |
    | statistics           | 0.000167 |
    | preparing            | 0.000038 |
    | executing            | 0.000005 |
    | Sending data         | 0.025582 |
    | end                  | 0.000012 |
    | query end            | 0.000007 |
    | closing tables       | 0.000008 |
    | freeing items        | 0.000041 |
    | logging slow query   | 0.000072 |
    | cleaning up          | 0.000013 |
    +----------------------+----------+
    17 rows in set (0.05 sec)
    

    以上表示在整个sql的生命周期中,每个阶段的耗时,可以看到耗时最长的环节是 Sending data,  想知道每个环节是什么意思,可以去mysql官网( https://dev.mysql.com/doc/refman/5.7/en/general-thread-states.html )查线程状态,比如Sending data, mysql官网是这么定义的:

    翻译过来就是:该线程正在读取和处理 SELECT 语句所检索出来的行,并将数据发送到客户端。由于在此状态期间发生的操作往往会执行大量磁盘访问(读取),因此它通常是给定查询生命周期中运行时间最长的状态。

    如果想知道更加具体的Sending data到底慢在cpu? 还是IO?还是其他什么地方,可以使用 show profile all for query 3;     

    从以上结果集可以看出,大部分时间都花在CPU上。

    彩蛋:如果你对mysql的源码感兴趣,可以使用show profile source for query 3;   可以看到具体每个操作定位到mysql源码的哪一行。

    end.

    支付宝扫一扫,为女程序员打赏!
    作者:梦幻朵颜
    版权:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    2018-2019-1 20165318 20165322 20165326 实验四 外设驱动程序设计
    2018-2019-1 20165318 实验三 实时系统
    2018-2019-1 20165318《信息安全系统设计基础》第九周课上测试
    2018-2019-1 20165318 20165322 20165326 实验二 固件程序设计
    2018-2019-1 20165318《信息安全系统设计基础》第八周课上测试
    2018-2019-1 20165318 20165322 20165326 实验一 开发环境的熟悉
    2018-2019-1 20165318《信息安全系统设计基础》第六周课上测试
    20165318 缓冲区溢出漏洞实验
    20165318 2017-2018-2《Java程序设计》课程总结
    缓冲区溢出漏洞实验
  • 原文地址:https://www.cnblogs.com/zhuwenjoyce/p/15032229.html
Copyright © 2020-2023  润新知