• 一个SQL引发的性能问题


    一个性能测试项目,一个值得深思的问题。

    1.症状:

    12小时稳定性压测,压力恒定

    系统响应时间随压测时间的增长而不断增大

    如图所示:

    2.性能分析,性能问题定位

    1)         系统负载检查:在压测过程中,压力恒定,CPU 利用率没有较大的波幅

    2)         磁盘IO检查:在压测过程中,磁盘读写稳定,没有较大的请求等待队列

    3)         网络检查:在压测过程中,无较大的数据传输,网络延迟正常,测试环境的网络正常。

    4)         内存检查:系统可用内存逐渐减小,JVM内存逐渐增大,不排除随着压测时间的增大而JVM崩溃的极端情况发生。

    通过分析jvm dump发现,在测试结束时,jvm内存在较多的与JDBC通信的等待线程。此类线程占用了较多的JVM内存空间

    根据上面的第4点,初步判断是与db的交互出现了性能问题。

    转到DB查看性能监控日志,对比测试开始和测试结束时的性能日志,发现其中一条SQL的查询性能差别极大。在初始时查询响应时间在10ms以下,但在测试结束时,达到800多毫秒,增幅达到80多倍,占据了整个transction响应时间的95%。

    获取该SQL的DB执行计划:

    可见该SQL在查询过程中使用了表扫描的操作,该操作的cost为2898,占据了99%的执行时间。

    再查询该表的大小, 发现该表在测试开始时仅有一千条左右的记录,但在测试结束时,已经增加到了30万条左右的记录,由此,真相大白,在测试刚开始时,表数据记录较少,即使使 用表扫描查询,DB响应也较快,但随着测试的进行,表中的记录迅速增长,此时,表扫描的性能迅速下降,成为性能瓶颈.

    3.性能调优

    知道了问题所在,解决起来就容易了

    SQL使用表扫描进行查询,是缺少了对应的索引,为此,我们给它建立了恰当的索引,在建立索引后,再查看该SQL的执行计划:

    如图所示,先前的Table access full 已经变为table access by index rowed ,消耗的资源由2898降低到4,完全解决了性能瓶颈。此时,再进行12小时的稳定性压测,系统性能稳定,不再出现响应时间不断增长的现象。

    通过该案例,可以得到一条有用性能经验,在记录增长较快的表中,即使初始查询的响应很快,也要为查询SQL建立合适的index,避免DB因为使用不恰当的执行计划而导致不必要的性能开销,从而避免系统产生数据查询上的性能瓶颈。

  • 相关阅读:
    数据库中的索引结构是什么?
    什么情况下适合建立索引?
    python requests https 访问出错
    Centos下 自动化配置SSH免密码登陆
    expect 批量增加用户及配置密码
    Shell 处理文件名中包含空格的文件
    Linux sort 命令
    ictclas bug修复
    [转]hadoop2.x常用端口
    在服务器上运行Jar包
  • 原文地址:https://www.cnblogs.com/s1328/p/4885551.html
Copyright © 2020-2023  润新知