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

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://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被弃用。

mybatis/callablestatement调用存储过程mysql connector产生不必要的元数据查询的更多相关文章

  1. mysql jdbc性能优化之mybatis/callablestatement调用存储过程mysql jdbc产生不必要的元数据查询(已解决,cpu负载减少20%)

    INFO | jvm 1 | 2016/08/25 15:17:01 | 16-08-25 15:17:01 DEBUG pool-1-thread-371dao.ITaskDao.callProce ...

  2. MyBatis中调用存储过程和函数

    一.调用存储过程 1.首先在数据库中定义存储过程,定义的存储过程的代码如下: //定义存储过程 create or replace procedure pag_add(p1 varchar2,p2 v ...

  3. java调用存储过程mysql

    在java中调用带返回值的存储过程的实现 直接上代码: DELIMITER $$ CREATE /*[DEFINER = { user | CURRENT_USER }]*/ PROCEDURE `t ...

  4. SpringMvc+Mybatis开发调用存储过程

    <mapper namespace="com.jkw100.ssm.mapper.CustomerMapperCustom" > <!-- statementTy ...

  5. mybatis注解调用存储过程

    mapper @SelectProvider(type = RoleMenuSqlProvider.class,method = "updateRoleMenuRelation") ...

  6. 在mybatis中调用存储过程的时候,不能加工语句

    select count(0) from ({call pkg_business.P_ZZS_LYFPHJSKJQK ('2018-04')}) 这是错误的.

  7. jdbc中的Statement对象和Preparedstatement对象的区别,以及通过jdbc操作调用存储过程

    一. java.sql.*   和  javax.sql.*的包的类结构 |- Driver接口: 表示java驱动程序接口.所有的具体的数据库厂商要来实现此接口. |- connect(url, p ...

  8. java 通过调用存储过程获取结果集

    一般在java中,数据查询是通过Statement, PreparedStatement获取结果集,今天向大家介绍通过CallableStatement调用存储过程,从而获取结果集.        本 ...

  9. Java代码调用存储过程和存储方法

    准备一个oracle 的JDBC jar 包:ojdbc14_11g.jar 首先找到你的 oracle 安装位置,例如: 1.创建一个JDBC数据库连接工具类: package com.test.d ...

随机推荐

  1. 程序员的复仇:11行代码如何让Node.js社区鸡飞狗跳

    来源自:http://www.techug.com/node-js-community 几天前,一名 NPM(Node.js Package Manager)社区的贡献者 Azer Koçulu 出于 ...

  2. 完成端口(Completion Port)详解(转)

    手把手叫你玩转网络编程系列之三    完成端口(Completion Port)详解                                                           ...

  3. lxde桌面默认快捷键

    ctrl+alt+左右      选择左右桌面shift+alt+左右     当前窗口送至左右桌面房子键+F1~F4       切换桌面1-4房子键+d           显示桌面alt+esc ...

  4. cwRsync window下的跨服务器的文件同步

    cwRsync 是window下的文件同步软件,可以跨服务器运行,第一次运行的时候是全部备份同步,之后的同步采用的是增量同步 这个软件分为服务端和客户端. 服务器是需要同步的文件源, 客户端相当于是备 ...

  5. js深拷贝和浅拷贝

    一.数组的深浅拷贝 在使用JavaScript对数组进行操作的时候,我们经常需要将数组进行备份,事实证明如果只是简单的将它赋予其他变量,那么我们只要更改其中的任何一个,然后其他的也会跟着改变,这就导致 ...

  6. 【PRML读书笔记-Chapter1-Introduction】1.5 Decision Theory

    初体验: 概率论为我们提供了一个衡量和控制不确定性的统一的框架,也就是说计算出了一大堆的概率.那么,如何根据这些计算出的概率得到较好的结果,就是决策论要做的事情. 一个例子: 文中举了一个例子: 给定 ...

  7. smartjs 0.2 OOP讲解 - Klass 类继承

    SmartJS2.0加入OOP的功能.OOP包括klass与factory两个对象. Klass 类继承 与其他的类继承相比,smartjs使用了执行指针的概念(后面例子中会介绍),另外提供base基 ...

  8. 在Visual Studio 2010中进行“项目重命名”的有效工具

    地址:http://www.cnblogs.com/dudu/archive/2011/12/11/visual_studio_2010_project_rename.html 提示:这个工具一次 r ...

  9. Mongodb For Windows

    关于 mongodb管理与安全认证 请移步这里: Mongodb For Mac OSX && 登录验证 安装mongodb 1. 官网下载 mongodb,如果嫌慢还可以前往百度云盘 ...

  10. JS中 escape, encodeURI 和 encodeURIComponent的区别

    为避免Url字符串在传递过程中的乱码,我们一般需要对字符串进行处理. 在Javascript中实现此功能的全局对象有3个,分别是:escape(),  encodeURI()  和 encodeURI ...