说明

今天发现个2个问题,一是mybatisplus执行一条某个字段值比较长(约1.8M的文本)的INSERT语句耗时要90s+;二是读取这个1.8M文本返回给前端耗时6min。查查查查了半天搞不清楚什么原因,最后在同事过来分析指点下立马解决。突然觉得自己像个沙比,特此记录,知耻后勇。另外也反思一下在查问题过程中的思路和方式问题。

问题1

现象

INSERT耗时过长

如图,SQL是单条记录更新,只不过第二个String比较大。下面是打印的耗时

当时分析思路

  1. 想验证一下此条INSERT语句通过navicat执行需要多长时间?

        

    复制出来执行一下,发现navicat执行需要16s左右,且返回的数据库response显示实际执行2s多。感觉是navicat在执行前后做了些业务操作如分析文本,导致要十几秒
  2. 验证原生jdbc执行效率

        

    通过原生jdbc执行多次发现执行时间在4s左右,还是相差甚远。开始怀疑是否mybatis是不是做了些文本分析才增加了耗时
  3. 验证mybatis的代理类执行效率

        

    构建了一个最简单的mybatis来执行,效率与jdbc相似也在4s左右,说明并没有
  4. 是否是事务等待?

        

    通过show processlist 和查询 information_schema.innodb_trx、innodb_locks、innodb_lock_waits发现执行此insert时并没有任何语句在执行,也就是说不存在事务等待
  5. 开始懵逼?

        

    想不通,看到ExecuteTime 139ms,觉得可能是mybatis里面哪个方法有问题,开始疯狂debug,不停debug,业务代码弄一下,mybatis源码弄一下,真的懵逼
  6. 寻求支援

        

    在同事的提示下猜测可能是打印日志拼接了过长的字符串所以耗时增加,原项目的日志等级不管怎么调,mybatis都在输出执行sql,无奈用回上面的 3 中的mybatis测试程序,将日志等级调整为ERROR,发现不输出日志和输出日志时间差异并不大,在10ms左右!然后我就放弃了思考。。。

后续解决

让同事过来帮忙一起看,他对于这个项目更熟悉,所以直接找到了mybatisplus的配置类,发现了一个PerformanceInterceptor,如下





此类中会打印执行的sql,难怪原项目怎么调日志等级都没用,原来在这里打印的





然后将此bean注释掉重新尝试一遍,那条执行时间长的 INSERT 立马丝滑,1s内就执行完成了。于是将此 bean 添加 @Profile("localdev") 注解,只在本地测试环境开启。

将代码提交后构建uat环境验证,结果无误,至此解决。

后续研究

本来想在本机复现,发现 PerformanceInterceptor 正常配置下只会打印 预编译sql,如下图





这样执行效率并没有受到影响,看来是某个实现将参数替换预编译中?的功能导致的低效问题。

这个替换功能目前网上主要是说要将log-impl设置为 StdOutImpl,但是尝试过无效,后续还是要找时间看看,不过可以不用太过纠结,毕竟这只是某个框架的配置的东西。

问题2

现象

1.8M左右的文本文件,将内容读取后以String返回,返回效率低花了6分钟。

分析过程

  1. 对比分析

        

    首先还是尝试用一个测试的Springboot项目来返回此文本文件,以判断是否是网络或者其他原因。

    测试结果发现相应速度很快,在200ms内。即使加大文本量到18M,相应时间也在700多ms,所以不是框架或者网络等原因。
  2. 怀疑是filter或者interceptor或者AOP处理response耗时过长

        

    项目内自定义的AOP过了一遍都没什么特别的处理。有两个自定义的与保留用户登录状态的token相关的filter,在他们的 chain.doFilter(request,response)方法前和该filter的 doFilter方法结尾都

    打印时间,发现第一个filter的start 和 end 隔得特别长,但是这个filter根本没做什么处理,就是一个 Map.remove的操作,所以肯定是有别的我没发现的filter在作怪。
  3. 交给其他同事

        

    由于对这块配置包括springSecurty不熟,并且还有别的项目要开发,项目经理建议交给其他同事来查此问题。

后续解决

是fastjson中对于web框架的传参出参做了处理,导致慢的。

后续研究

tomcat中注册了哪些filter可以通过 chain 这个对象来看

总结

  1. 最后回头来看,其实我对于问题的分析思路基本上都是正确的,就差在熟悉程度上,对于框架的操作使用,问题排查还是需要多写多练才能提升经验。
  2. 不要被情绪影响,在查问题很大一部分影响因素是心态和情绪。当时的情况是有另一个项目需要开发,前端要找我对接;并且现场部署的产品有问题,报障群其他人都在装死;这个性能问题昨天已经解了一天,解决完部分问题后又冒出了这些新问题;

    这三连击加起来让我在不同的项目中来回切换,并且产生了焦躁情绪,甚至在怀疑自己,这些都会阻碍思考。
  3. 后续做事要分清轻重缓急,并且心态要放平和,用观察者心态来处理情绪。还需要多积累分析解决问题的实际经验,分析问题中不要死磕去debug。

    至此

记一次mybatis性能问题分析过程的更多相关文章

  1. 记一次Java Core Dump分析过程

    #背景提要 很久没有亲自动手部署代码了,命令行的亲切感越来越低.放飞了键盘,习惯了鼠标操作的windows环境.冷不丁实操部署也是不错的. 常常在部署时,运维同学对于[hs_err_pid]文件视而不 ...

  2. mybatis源码分析(五)------------SQL的执行过程

    在对SQL的执行过程进行分析前,先看下测试demo: /** * @author chenyk * @date 2018年8月20日 */ public class GoodsDaoTest { pr ...

  3. MyBatis 源码分析 - SQL 的执行过程

    * 本文速览 本篇文章较为详细的介绍了 MyBatis 执行 SQL 的过程.该过程本身比较复杂,牵涉到的技术点比较多.包括但不限于 Mapper 接口代理类的生成.接口方法的解析.SQL 语句的解析 ...

  4. MyBatis 源码分析 - 映射文件解析过程

    1.简介 在上一篇文章中,我详细分析了 MyBatis 配置文件的解析过程.由于上一篇文章的篇幅比较大,加之映射文件解析过程也比较复杂的原因.所以我将映射文件解析过程的分析内容从上一篇文章中抽取出来, ...

  5. MyBatis 源码分析 - 配置文件解析过程

    * 本文速览 由于本篇文章篇幅比较大,所以这里拿出一节对本文进行快速概括.本篇文章对 MyBatis 配置文件中常用配置的解析过程进行了较为详细的介绍和分析,包括但不限于settings,typeAl ...

  6. 使用Django.core.cache操作Memcached导致性能不稳定的分析过程

    使用Django.core.cache操作Memcached导致性能不稳定的分析过程 最近测试一项目,用到了Nginx缓存服务,那可真是快啊!2Gb带宽都轻易耗尽. 不过Api接口无法简单使用Ngin ...

  7. 性能测试——记XX银行保全项目性能问题分析优化

    记XX银行保全项目性能问题分析优化 数据库问题也许是大部分性能问题的关注点,但是JAVA应用与数据库交互的关节,JDBC 就像是我们人体的上半身跟下半身的腰椎,支持上半身,协调下半身运动的重要支撑点. ...

  8. 精尽MyBatis源码分析 - MyBatis 的 SQL 执行过程(一)之 Executor

    该系列文档是本人在学习 Mybatis 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释(Mybatis源码分析 GitHub 地址.Mybatis-Spring 源码分析 GitHub ...

  9. 精尽MyBatis源码分析 - SQL执行过程(二)之 StatementHandler

    该系列文档是本人在学习 Mybatis 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释(Mybatis源码分析 GitHub 地址.Mybatis-Spring 源码分析 GitHub ...

  10. 精尽MyBatis源码分析 - SQL执行过程(三)之 ResultSetHandler

    该系列文档是本人在学习 Mybatis 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释(Mybatis源码分析 GitHub 地址.Mybatis-Spring 源码分析 GitHub ...

随机推荐

  1. 高清地图转换(xord转apollo的bin文件)

    目标 将carla中的OpenDrive地图(carla\Unreal\CarlaUE4\Content\Carla\Maps\OpenDrive)转换为Apollo中可识别的地图格式(bin与txt ...

  2. KingbaseES V8R6集群维护案例之---将securecmdd通讯改为ssh案例

    案例说明: 在KingbaseES V8R6的后期版本中,为了解决有的主机之间不允许root用户ssh登录的问题,使用了securecmdd作为集群部署分发和通讯的服务,有生产环境通过漏洞扫描,在88 ...

  3. KingbaseES V8R6集群部署案例之---Windows环境配置主备流复制(异机复制)

    案例说明: 目前KingbaseES V8R6的Windows版本不支持数据库sys_rman的物理备份,可以考虑通过建立主备流复制实现数据库的异机物理备份.本案例详细介绍了,在Windows环境下建 ...

  4. Oracle与KingbaseES的NULL在索引使用上的区别

    NULL值是关系型数据库系统中比较特殊的一种值,通常称为UNKNOWN或空值,即是未知的,不确定的.由于NULL存在着无数的可能,因此NULL值也不等于NULL值. Oracle在创建索引时,不会存储 ...

  5. dp-LIS LCS 模型

    最长上升子序列问题: https://www.cnblogs.com/sxq-study/p/12303589.html 一:两遍LIS问题 1:题目: 怪盗基德是一个充满传奇色彩的怪盗,专门以珠宝为 ...

  6. 注解@PostConstruct分析

    作用 1.注解@PostConstruct可以添加在类的方法上面,如果这个类被IOC容器托管,那么在对Bean进行初始化前的时候会调用被这个注解修饰的方法 被定义在哪里? 1.被定义在了CommonA ...

  7. 《网页设计基础——HTML注释与CSS注释》

    网页设计基础--HTML注释与CSS注释       一.HTML注释: 格式: <!-- 在此处书写注释 --> 例如: <html> <head> <ti ...

  8. Visual Studio 2022 Community 不完全攻略

    0. 前言 建议结合视频阅读哦 Visual Studio 2022 Community 不完全攻略 有问题或者意见欢迎评论 ! 1. 下载&安装 Visual Studio Communit ...

  9. .NET 7 来了!!!

    .NET 7 首个RC(发布候选)版本 最近 .Net 的大事件,就是微软发布了.NET 7的首个RC(发布候选)版本,而据微软发布的消息,这是 .NET 7 的最后一个预览版,下一个版本将是第一个候 ...

  10. 在k8s中部署前后端分离项目进行访问的两种配置方式

    第一种方式 (1) nginx配置中只写前端项目的/根路径配置 前端项目使用的Dockerfile文件内容 把前端项目编译后生成的dist文件夹放在nginx的html默认目录下,浏览器访问前端项目时 ...