springmvc controller 查询数据慢追踪

原创
2020/06/12 16:10
阅读数 1.3K

问题描述

 公司后台系统线上环境出现用户正常使用期会出现系统慢问题,缓慢问题无法有效解决. 领导说慢是service添加了整事物覆盖导致,如果多线程访问同一条记录会有等待情况,如果不需要只读事物是会加快查询,把Transcational(readOnly) 去掉

@Service
@Transactional(readOnly = true)
public class XxService

我回答是说 跟这个没多大关系.mysql5.6以前会区分引擎 mysan与innodb 区别。现在优化越来越好两个类型已经没区别了。只读去掉不去掉都无太大影响

本着领导检查原则。让我做这块验证说法我就做本次记录. 如有不正确还请指出

系统是接入过 SkyWalking 的 .通过系统接入SkyWalking 进行监控查看,

 拿出频率比较高接口慢原因 猜测点围绕 以下点

     1.只读事物影响

     系统内每个service都会开启事物 查询走只读事物, 更新走读写事物, 而只读事物特点在于防止数据脏读。

     目前系统大部分业务不存在脏读情况。如果去掉只读事物是否在更新同时不需要等待时间直接查询返回而提高效率

问题分析

监控图看到 .数据库总量单表在1千万左右 访问url.

SkyWalking监控到的图,同一个接口慢话 1-100秒响应时间不等而一条完整追踪链 显示 间隔较长 就是耗时时间较长点 都是查询sql之前发的

select @@session.tx_read_only  再到语句过程耗时较多。如果一个接口查询过多数据就会导致 耗时更长, 是否这个tx_read_only  额外查询导致慢

通过 资料,找到了原因:

    此sql的作用主要是判断事务是否为只读事务。MySQL自身会对只读事务做优化,这是MySQL5.6.5 版本以后才出现的。http://dev.mysql.com/doc/refman/5.6/en/server-system-variables.html#sysvar_tx_read_only

    定位到MySQL的驱动包代码

一般情况下,驱动可以保证本地值与远程服务器值保持一致。当应用调用setAutoCommit, setTransactionIsolation 和 setReadOnly这三个接口设置参数值时,会与远程服务器同步。

具体而言

当useLocalSessionState为true时,若值与本地值不一致,则发往远程更新;
当useLocalSessionState为false时,无论设置值与本地值是否一致,每次都发往远程更新。这可以解释为什么有些实例set autocommit语句比较多。

所以第一条跟这个无关系select @tx_read_only  这个只是保证本地查询事物与mysql数据端一致做的同步,并不影响效率.

接下来是事物问题 建在本地弄了同样级别数据量1千6百万, 统计一下就花了23秒

再继续添加验证

分别添加controller,service.mybatis ,service 通过删除Transcational标记和加上来进行测试

创建查询线程测试几个场景 去掉Transactionl测试查询影响

 1.service保留Transactionl  , 查询11个运单同时开启3个线程 耗时 1:08, 1:06 , 1:06, 进行读写读测试 a个线程先读(结果:test1),b线程开始写(结果:test2),c线程再读(结果:test1),d线程跟读(结果:test1). 分别时间未 1:18,1:24, 1:16,1:16

 2.service去掉Transactionl ,  查询11个运单同时开启3个线程 耗时 1:09 ,1:10, 1:10, 进行读写读测试 a个线程先读(结果:test1),b线程开始写(结果:test2),c线程再读(结果:test1),d线程跟读(结果:test1). 分别时间未 1:17,1:25, 1:15,1:14

在jdbc加上默认tx_read_only,及去掉Transactionl测试影响结果同上

结论总结

 查阅众多资料及验证。mysql默认事物隔离( Repeatable read )基本验证基本一致,存在锁情况一般为更高基本事物隔离( Serializable )

 而service 加Transactionl 是一种规范问题。加上Transactionl (readonly=false) 表示会默认优化事物只读. 如果不加 则默认读写事物, 细化到方法未写readonly遗忘也没关系.

优化数据库查询只能更改mysql数据几个事物级别再次降低。及库语句优化,缓存处理.我们这个缓存也没少加.系统总体体量过大 查询统计语句过多。服务器资源有限. 如果在其他地方瘦身后。使依赖查询数据库频率降低,资源也就出来了。不会导致平常走索引单条几条查询出现 响应时间长短不一结果.

 

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
0 评论
0 收藏
0
分享
返回顶部
顶部