mybatis/callablestatement调用存储过程mysql jdbc产生不必要的元数据查询(已解决,cpu负载减少20%)
2016-08-25 15:42
435 查看
INFO | jvm 1 | 2016/08/25 15:17:01 | 16-08-25 15:17:01 DEBUG pool-1-thread-371dao.ITaskDao.callProcedure: ==> Preparing: call sp_one( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? );
INFO | jvm 1 | 2016/08/25 15:17:01 | 16-08-25 15:17:01 DEBUG pool-1-thread-371 dao.ITaskDao.callProcedure: ==> Parameters: 9999(Integer), 9901(Integer),=(String), task(String), T(String), 1000(Integer), sysL.1.19(String), 13(Integer), 469047(Integer), 20160825(Integer), 151700(Integer)
INFO | jvm 1 | 2016/08/25 15:17:01 | 16-08-25 15:17:01 DEBUG pool-1-thread-371.dao.ITaskDao.callProcedure: <== Total: 1
INFO | jvm 1 | 2016/08/25 15:17:01 | 16-08-25 15:17:01 DEBUG pool-1-thread-371dao.ITaskDao.callProcedure: <== Updates: 0
![](https://oscdn.geek-share.com/Uploads/Images/Content/202006/06/179b83699983254c74625595720682a8.png)
根据https://www.percona.com/blog/2006/08/02/mysql-prepared-statements/所述,mysql的Prepare Statements目前好像只能如此,原生mysql jdbc驱动也没支持改进。MariaDB Connector/J倒是进行了优化。
需要使用最古老的
CallableStatement cs = (CallableStatement)statement;
cs.execute();
int rows = cs.getUpdateCount();
看来目前只能使用mariadb connector了,就怕这不稳定要么有特定bug存在。。。
我们使用的mysql connector版本是5.1.34。希望后续版本能够优化掉问题。
=============
170222更新
这个最近我们已经解决了,在jdbc.url连接串中增加选项如下:
cachePrepStmts=true
2017-02-22T18:47:51.004298+08:00 31744 Query SELECT * FROM `c3potest`
2017-02-22T18:47:51.004677+08:00 31753 Query SELECT * FROM `c3potest`
2017-02-22T18:47:51.840092+08:00 30929 Query SELECT * FROM `c3potest`
2017-02-22T18:47:51.840828+08:00 30929 Query call prl_QueryUniteQuitiesPosition(
7777,77770002,'YWQzYzM3ZTlkOTNjYzFlNzJjNWEzNzUzNDc2OGUyYTI=','101.69.255.190:41723>=ld-web','7',806003,'actL.2.7',7777,0,' ',0,'',0,'',0,0,@com_mysql_jdbc_outparam_p_error_code,@com_mysql_jdbc_outparam_p_error_info
)
2017-02-22T18:47:51.846647+08:00 30929 Query SELECT @com_mysql_jdbc_outparam_p_error_code,@com_mysql_jdbc_outparam_p_error_info
2017-02-22T18:47:51.847462+08:00 30929 Query SELECT * FROM `c3potest`
2017-02-22T18:47:52.001402+08:00 31753 Query select * from tb_sys_task
2017-02-22T18:47:52.003294+08:00 31744 Query select unix_timestamp()
最新版本的5.1.41已经发布,意味着可以使用useConfigs=maxPerformance了,同时,elideSetAutoCommits因为bug被弃用。
INFO | jvm 1 | 2016/08/25 15:17:01 | 16-08-25 15:17:01 DEBUG pool-1-thread-371 dao.ITaskDao.callProcedure: ==> Parameters: 9999(Integer), 9901(Integer),=(String), task(String), T(String), 1000(Integer), sysL.1.19(String), 13(Integer), 469047(Integer), 20160825(Integer), 151700(Integer)
INFO | jvm 1 | 2016/08/25 15:17:01 | 16-08-25 15:17:01 DEBUG pool-1-thread-371.dao.ITaskDao.callProcedure: <== Total: 1
INFO | jvm 1 | 2016/08/25 15:17:01 | 16-08-25 15:17:01 DEBUG pool-1-thread-371dao.ITaskDao.callProcedure: <== Updates: 0
mysql general_log中可以发现如下元数据查询语句: SELECT name, type, comment FROM mysql.proc WHERE name like... SHOW FUNCTION STATUS LIKE 'sp_one' SHOW PROCEDURE STATUS LIKE 'sp_one' SHOW CREATE PROCEDURE `db-name`.`sp_one` CALL sp_one()
因为我们使用了大量的存储过程,而且很多过程执行非常快,因此导致查询这些元数据本身成了响应时间中很大的一部分,如下所示:
![](https://oscdn.geek-share.com/Uploads/Images/Content/202006/06/179b83699983254c74625595720682a8.png)
根据https://www.percona.com/blog/2006/08/02/mysql-prepared-statements/所述,mysql的Prepare Statements目前好像只能如此,原生mysql jdbc驱动也没支持改进。MariaDB Connector/J倒是进行了优化。
需要使用最古老的
stmt = conn.createStatement(); rs = stmt.executeQuery("call sp_one('a','b')");才能解决该问题。 mybatis的实现中,CALLABLE直接调用了callablestatement,没法直接运行,如下:
CallableStatement cs = (CallableStatement)statement;
cs.execute();
int rows = cs.getUpdateCount();
看来目前只能使用mariadb connector了,就怕这不稳定要么有特定bug存在。。。
我们使用的mysql connector版本是5.1.34。希望后续版本能够优化掉问题。
=============
170222更新
这个最近我们已经解决了,在jdbc.url连接串中增加选项如下:
cachePrepStmts=true
cacheCallableStmts=true cacheServerConfiguration=true useLocalSessionState=true elideSetAutoCommits=false alwaysSendSetIsolation=false enableQueryTimeouts=false useConfigs=maxPerformance有bug https://bugs.mysql.com/bug.php?id=70785等待下一版本发布解决。 如下,大量日志都没有了
2017-02-22T18:47:51.004298+08:00 31744 Query SELECT * FROM `c3potest`
2017-02-22T18:47:51.004677+08:00 31753 Query SELECT * FROM `c3potest`
2017-02-22T18:47:51.840092+08:00 30929 Query SELECT * FROM `c3potest`
2017-02-22T18:47:51.840828+08:00 30929 Query call prl_QueryUniteQuitiesPosition(
7777,77770002,'YWQzYzM3ZTlkOTNjYzFlNzJjNWEzNzUzNDc2OGUyYTI=','101.69.255.190:41723>=ld-web','7',806003,'actL.2.7',7777,0,' ',0,'',0,'',0,0,@com_mysql_jdbc_outparam_p_error_code,@com_mysql_jdbc_outparam_p_error_info
)
2017-02-22T18:47:51.846647+08:00 30929 Query SELECT @com_mysql_jdbc_outparam_p_error_code,@com_mysql_jdbc_outparam_p_error_info
2017-02-22T18:47:51.847462+08:00 30929 Query SELECT * FROM `c3potest`
2017-02-22T18:47:52.001402+08:00 31753 Query select * from tb_sys_task
2017-02-22T18:47:52.003294+08:00 31744 Query select unix_timestamp()
最新版本的5.1.41已经发布,意味着可以使用useConfigs=maxPerformance了,同时,elideSetAutoCommits因为bug被弃用。
相关文章推荐
- MS Sqlserver优化实战(解决CPU利用率高及查询操作速度慢)
- 调用javascript里的中文信息时产生乱码的解决方法
- 解决:Java调用.net的webService产生“服务器未能识别 HTTP 标头 SOAPAction 的值”错误
- Mybatis调用存储过程返回查询语句
- iBatis多次调用同一查询语句查询时报“列名无效”无列名的错误原因及解决方法
- 诊断并解决ajax异步调用产生的后遗症
- php-cgi进程占用cpu资源过多负载高的原因分析及解决步骤
- 调用SendMessage 产生死锁的解决方法
- 通达OA 缓慢,打开页面速度十分慢,cpu 负载高 如何解决?
- 解决 kettle 调用informix 设置数据源 查询中文乱码
- 在access的vba中循环调用带参数查询时遇到的问题及解决办法
- java cpu负载过高的查询方法
- MS Sqlserver优化实战(解决CPU利用率高及查询操作速度慢)
- php-cgi进程占用cpu资源过多负载高的原因分析及解决步骤
- php-cgi进程占用cpu资源过多负载高的原因分析及解决步骤
- AX中动态产生方法并且调用,解决根据不同条件产生不同SQL逻辑的问题很方便
- MS Sqlserver优化实战(解决CPU利用率高及查询操作速度慢)
- 进程占用cpu资源过多负载高的原因分析及解决步骤
- php-cgi进程占用cpu资源过多负载高的原因分析及解决步骤
- android 调用系统相机方法,解决CPU兼容问题