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

当时分析思路
- 想验证一下此条INSERT语句通过navicat执行需要多长时间?
复制出来执行一下,发现navicat执行需要16s左右,且返回的数据库response显示实际执行2s多。感觉是navicat在执行前后做了些业务操作如分析文本,导致要十几秒 - 验证原生jdbc执行效率
通过原生jdbc执行多次发现执行时间在4s左右,还是相差甚远。开始怀疑是否mybatis是不是做了些文本分析才增加了耗时 - 验证mybatis的代理类执行效率
构建了一个最简单的mybatis来执行,效率与jdbc相似也在4s左右,说明并没有 - 是否是事务等待?
通过show processlist 和查询 information_schema.innodb_trx、innodb_locks、innodb_lock_waits发现执行此insert时并没有任何语句在执行,也就是说不存在事务等待 - 开始懵逼?
想不通,看到ExecuteTime 139ms,觉得可能是mybatis里面哪个方法有问题,开始疯狂debug,不停debug,业务代码弄一下,mybatis源码弄一下,真的懵逼 - 寻求支援
在同事的提示下猜测可能是打印日志拼接了过长的字符串所以耗时增加,原项目的日志等级不管怎么调,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分钟。
分析过程
- 对比分析
首先还是尝试用一个测试的Springboot项目来返回此文本文件,以判断是否是网络或者其他原因。
测试结果发现相应速度很快,在200ms内。即使加大文本量到18M,相应时间也在700多ms,所以不是框架或者网络等原因。 - 怀疑是filter或者interceptor或者AOP处理response耗时过长
项目内自定义的AOP过了一遍都没什么特别的处理。有两个自定义的与保留用户登录状态的token相关的filter,在他们的 chain.doFilter(request,response)方法前和该filter的 doFilter方法结尾都
打印时间,发现第一个filter的start 和 end 隔得特别长,但是这个filter根本没做什么处理,就是一个 Map.remove的操作,所以肯定是有别的我没发现的filter在作怪。 - 交给其他同事
由于对这块配置包括springSecurty不熟,并且还有别的项目要开发,项目经理建议交给其他同事来查此问题。
后续解决
是fastjson中对于web框架的传参出参做了处理,导致慢的。
后续研究
tomcat中注册了哪些filter可以通过 chain 这个对象来看

总结
- 最后回头来看,其实我对于问题的分析思路基本上都是正确的,就差在熟悉程度上,对于框架的操作使用,问题排查还是需要多写多练才能提升经验。
- 不要被情绪影响,在查问题很大一部分影响因素是心态和情绪。当时的情况是有另一个项目需要开发,前端要找我对接;并且现场部署的产品有问题,报障群其他人都在装死;这个性能问题昨天已经解了一天,解决完部分问题后又冒出了这些新问题;
这三连击加起来让我在不同的项目中来回切换,并且产生了焦躁情绪,甚至在怀疑自己,这些都会阻碍思考。 - 后续做事要分清轻重缓急,并且心态要放平和,用观察者心态来处理情绪。还需要多积累分析解决问题的实际经验,分析问题中不要死磕去debug。
至此
记一次mybatis性能问题分析过程的更多相关文章
- 记一次Java Core Dump分析过程
#背景提要 很久没有亲自动手部署代码了,命令行的亲切感越来越低.放飞了键盘,习惯了鼠标操作的windows环境.冷不丁实操部署也是不错的. 常常在部署时,运维同学对于[hs_err_pid]文件视而不 ...
- mybatis源码分析(五)------------SQL的执行过程
在对SQL的执行过程进行分析前,先看下测试demo: /** * @author chenyk * @date 2018年8月20日 */ public class GoodsDaoTest { pr ...
- MyBatis 源码分析 - SQL 的执行过程
* 本文速览 本篇文章较为详细的介绍了 MyBatis 执行 SQL 的过程.该过程本身比较复杂,牵涉到的技术点比较多.包括但不限于 Mapper 接口代理类的生成.接口方法的解析.SQL 语句的解析 ...
- MyBatis 源码分析 - 映射文件解析过程
1.简介 在上一篇文章中,我详细分析了 MyBatis 配置文件的解析过程.由于上一篇文章的篇幅比较大,加之映射文件解析过程也比较复杂的原因.所以我将映射文件解析过程的分析内容从上一篇文章中抽取出来, ...
- MyBatis 源码分析 - 配置文件解析过程
* 本文速览 由于本篇文章篇幅比较大,所以这里拿出一节对本文进行快速概括.本篇文章对 MyBatis 配置文件中常用配置的解析过程进行了较为详细的介绍和分析,包括但不限于settings,typeAl ...
- 使用Django.core.cache操作Memcached导致性能不稳定的分析过程
使用Django.core.cache操作Memcached导致性能不稳定的分析过程 最近测试一项目,用到了Nginx缓存服务,那可真是快啊!2Gb带宽都轻易耗尽. 不过Api接口无法简单使用Ngin ...
- 性能测试——记XX银行保全项目性能问题分析优化
记XX银行保全项目性能问题分析优化 数据库问题也许是大部分性能问题的关注点,但是JAVA应用与数据库交互的关节,JDBC 就像是我们人体的上半身跟下半身的腰椎,支持上半身,协调下半身运动的重要支撑点. ...
- 精尽MyBatis源码分析 - MyBatis 的 SQL 执行过程(一)之 Executor
该系列文档是本人在学习 Mybatis 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释(Mybatis源码分析 GitHub 地址.Mybatis-Spring 源码分析 GitHub ...
- 精尽MyBatis源码分析 - SQL执行过程(二)之 StatementHandler
该系列文档是本人在学习 Mybatis 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释(Mybatis源码分析 GitHub 地址.Mybatis-Spring 源码分析 GitHub ...
- 精尽MyBatis源码分析 - SQL执行过程(三)之 ResultSetHandler
该系列文档是本人在学习 Mybatis 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释(Mybatis源码分析 GitHub 地址.Mybatis-Spring 源码分析 GitHub ...
随机推荐
- 关于MicroPython mpremote工具 的一些用例,闲聊
关于MicroPython mpremote工具 的一些用例,闲聊 我尝试了很多不同的第三方micropython工具,有些是Windows应用程序,有些是VScode插件. 但是当我尝试过Micro ...
- KingbaseES where 条件解析顺序
概述 KingbaseES 对于where 条件的解析严格遵守"从左到右"的原则,因此,对于选择性比较强的条件,进行最先过滤是有利于性能的. 一.KingbaseES 1.条件顺序 ...
- python的环境,你再也不用愁-conda
Conda Guide Conda简介 conda是一个包,依赖和环境管理工具,适用于多种语言,如: Python, R, Scala, Java, Javascript, C/ C++, FORTR ...
- CentOS7使用yum方式安装Containerd
# 安装需要的软件包, yum-util 提供yum-config-manager功能,另外两个是devicemapper驱动依赖的 yum install -y yum-utils device-m ...
- go-fastdfs和配套使用的web页面
go-fastdfs go-fastdfs是一个基于http协议的分布式文件系统,它基于大道至简的设计理念,一切从简设计,使得它的运维及扩展变得更加简单,它具有高性能.高可靠.无中心.免维护等优点. ...
- 第一个Django应用 - 第六部分:静态文件
前面我们编写了一个经过测试的投票应用,现在让我们给它添加一张样式表和一张背景图片. 除了由服务器生成的HTML文件外,WEB应用一般需要提供一些其它的必要文件,比如图片文件.JavaScript脚本和 ...
- 采用阿里云 yum的方式安装ceph
首先机器需要联网,并且配置网络yum源,epel源,可从阿里开源镜像站中下载源文件. 注:EPEL (Extra Packages for Enterprise Linux)是基于Fedora的一个项 ...
- SVM公式详尽推导,没有思维跳跃。
假定数据集\(T=\{(x_1,y_1),(x_2,y_2),...,(x_n,y_n)\},x_n \in R_k, y_n \in \{1,-1\}\)线性可分,SVM的优化目标是: 优化一个超平 ...
- .NET6 使用 AutoFac (解析)
一.Net 6环境下的.net core项目里如何使用Autofac实现依赖注入. 通常的,我们把其他服务注入到Controller时,使用.net core自带的依赖注入即可,但是如果我们要实现自定 ...
- css百叶窗
效果图: css代码块: <style> *{//默认样式清除 margin: 0; padding: 0; } .content{//设置外层div的宽高,超出后隐藏 margin: 1 ...