jdbc测试mysql数据库sql预解析(绑定变量)

用习惯了oracle,学习mysql,想测试一下mysql绑定变量的效果。以前看网上介绍大部份都说mysql没有sql共享池的概念,所以也不存在sql预解析或绑定变量的说法。

今天测试了一下(通过网络抓包、查看服务器端sql日志及分析源码等方法),发现mysql还是有sql预解析的实现。

服务器端是mysql 5.1.58(win32),用jdbc(5.1.18)做客户端,默认的连接方式是不会有sql预解析效果,即使我们用PreparedStatement对象也差不多,它只是把SQL和变量拼接成一个完整的SQL发送给服务器,如下代码:

PreparedStatement pstmt = conn.prepareStatement("select * from t1 where c1=?");

pstmt.setString(1, "abc");

pstmt.execute();

实际上不会有预解析的过程,而是经过简单的拼接,把如下SQL发送给服务器

select * from t1 where c1='abc' 要实现预解析的效果,我们必须设置jdbc Connection的参数useServerPrepStmts=true,再使用PreparedStatement后就OK了,创建PreparedStatement时客户端先把"select * from t1 where c1=?"发送到服务器端预解析,execute时只是把变量传送到服务器执行。

mysql服务器的sql语句缓存可以通过状态变量Prepared_stmt_count查看

mysql> show status like 'Prepared_stmt_count';

+---------------------+-------+

| Variable_name | Value |

+---------------------+-------+

| Prepared_stmt_count | 1 |

+---------------------+-------+

1 row in set

不过mysql的sql语句缓存与oracle有很大不同,它是会话语句级的,不是全局共享,当会话断开或PreparedStatement.close后这个缓存就没有了。我们需要设置Connection的参数cachePrepStmts=true把PreparedStatement缓存起来,prepStmtCacheSize=xxx来设置每个会话缓存语句的最大数量(很多连接池也有类似的功能)。

OK,已经知道如何启用预解析了,想看看启用与不启用预解析性能有多少差别,会不会也像oracle那么明显呢?经过简单的测试,发现当没有PreparedStatement缓存(cachePrepStmts=false)时,打开预解析性能下降很多, 当有PreparedStatement缓存(cachePrepStmts=true)时,两者性能基本一样。这个结果让人很失望,个人分析有几个原因:

启用预解析但没有PreparedStatement缓存时,每次创建PreparedStatement都需要解析一次,execute时又需要交互一次,而预解析的SQL在PreparedStatement.close又不能重用,所以性能反而更差。

当有PreparedStatement缓存时,预解析的SQL文本缓存在服务器端,但是并不会像oracle一样缓存执行计划,所以每次execute时都需要解析SQL和生成执行计划,因此只是减少了每次execute传输SQL的文本大小,性能差别不大。

注:如果SQL语法错误,那么服务器端预解析会出错,但jdbc收到预解析出错的信息后并不提示出错,而是将取消本条语句预解析的状态,execute时直接把SQL接装发送给服务器,mysql jdbc在PreparedStatement构造函数中代码如下,其中返回ServerPreparedStatement类表示使用了绑定变量,返回PreparedStatement表示未使用绑定变量:

try {

pStmt = ServerPreparedStatement.getInstance(getLoadBalanceSafeProxy(), nativeSql,

this.database, resultSetType, resultSetConcurrency);

pStmt.setResultSetType(resultSetType);

pStmt.setResultSetConcurrency(resultSetConcurrency);

} catch (SQLException sqlEx) {

// Punt, if necessary

if (getEmulateUnsupportedPstmts()) {

pStmt = (PreparedStatement) clientPrepareStatement(nativeSql, resultSetType, resultSetConcurrency, false);

} else {

throw sqlEx;

}

} 经过上面分析,个人认为不需要打开SQL预解析的效果,PreparedStatement对象还是尽量使用,因为虽然不能提升性能,但可以避免SQL注入安全问题 。

2012-02-17

分享到:

2012-02-17 00:07

浏览 764

评论

mysql jdbc 绑定变量_jdbc测试mysql数据库sql预解析(绑定变量)相关推荐

  1. mysql jdbc 分页查询_JDBC与MySQL实现分页查询技术

    由于通过ResultSet的光标实现数据分页存在占用大量资源等性能方便的缺陷,所以,在实际开发中,通过采用数据库的分页机制来实现分页查询功能更为上上之策. 下面我就通过MySQL数据库提供的分页机制来 ...

  2. mysql jdbc连接失败_JDBC连接MySQL失败

    梳理一下连接需要注意的关键点 1.首先需要导入外部的驱动jar包,jar包与MySQL的版本最好对应,一般都是用最新的就没问题. 2.最新驱动加载时要使用Class.forname("com ...

  3. centos mysql jar 驱动包_JDBC连接MySQL的数据库

    JDBC连接MySQL的数据库 开发工具:eclipes 数据库:mysql 5.6 jdk:1.8 目的:通过简单示例,教会大家如何通过java的代码实现的MySQL的数据库访问. 访问数据库:首先 ...

  4. mysql jdbc无法连接_jdbc无法连接mysql

    mysql_connector_java_5.1.34_bin.jar(5.1.19驱动也不行) mysql5.6 代码: private static String JDBCDriver=" ...

  5. java.lang.ClassCastException: com.mysql.jdbc.Driver cannot be cast to javax.sql.DataSource

    错误描述: Spring Boot 项目启动时出现错误:java.lang.ClassCastException: com.mysql.jdbc.Driver cannot be cast to ja ...

  6. 本地mysql拒绝jdbc连接失败_jdbc连接MySQL数据库的诡异异常 java.net.ConnectException: 拒绝连接...

    今天遇到一个很诡异的异常,查了很多资料都没有解决. 用JDBC连接数据库的时候出现以下异常 @Test public void test() { try { Class.forName("c ...

  7. jdbc mysql 存储过程查询数据_JDBC连接(MySql)数据库步骤,以及查询、插入、删除、更新等十一个处理数据库信息的功能。...

    主要内容: JDBC连接数据库步骤. 一个简单详细的查询数据的例子. 封装连接数据库,释放数据库连接方法. 实现查询,插入,删除,更新等十一个处理数据库信息的功能.(包括事务处理,批量更新等) 把十一 ...

  8. jdbc mysql 自动重连_JDBC实现Mysql自动重连机制的方法详解

    JDBC是Java程序连接和访问各种数据库的API,它可以提供Java程序和各种数据库之间的连接服务,下面是爱站技术频道小编为大家带来的JDBC实现Mysql自动重连机制的方法详解. 日志:using ...

  9. Java数据库部分(MySQL+JDBC)(一、MySQL超详细学习笔记)

    所有示例使用的数据表均为Oracle提供的SQL基础数据表(t_employees.sql dept.sql emp.sql salgrade.sql) 熟练掌握多多练习即可达到完成后端开发所需具备的 ...

最新文章

  1. PXE启动芯片出错代码表、初始化/引导/载入Bootstrap错误代码
  2. 上证50ETF申赎清单
  3. 如何在React中做到jQuery-free
  4. python怎么和sql一起用_自己写的Python数据库连接类和sql语句拼接方法
  5. C++学习基础八——重载输入和输出操作符
  6. 【Transformer】ATS: Adaptive Token Sampling For Efficient Vision Transformers
  7. ASP.NET MVC 1.0 + spring.net 1.2.0.20288 + NHibernate 2.0.1.4000整合笔记(三)——NHibernate配置...
  8. windows系统改装为linux系统_Linux怎么克隆系统?备份系统跟Windows系统有区别吗?...
  9. access 动态 top 条件_2020年10月抖音直播营销报告_行业动态
  10. 【OpenCV】OpenCV函数精讲之 -- addWeighted()函数(线性混合)
  11. Flutter的AnimatedDefaultTextStyle实现文本样式的动画过渡切换效果
  12. 超外差和超再生模块有何区别?
  13. ASP经典分页类(改良后的分页类主要是显示属性)
  14. J2EE基础篇——十三个规范
  15. updata pip 报错 TypeError: parse() got an unexpected keyword argument 'transport_encoding'
  16. Python 提示‘Unindent amount does not match previous indent‘解决方法
  17. 哄女朋友必备之微信自动发红包脚本(python+adb+androidviewclient)
  18. layui表格换行,有固定列的情况
  19. Windows10中Edge浏览器突然出现“无法访问该页面”问题的解决方案
  20. 引流复盘:从知乎引流20万粉,我只用了1个月

热门文章

  1. JAVA学习--集合的遍历
  2. DB2中admin_cmd执行load
  3. pytorch梯度下降函数_Pytorch中常用的四种优化器SGD、Momentum、RMSProp、Adam
  4. python实现路由功能_python 实现重启路由器
  5. nodejs 安装 nrm
  6. 启动TOMCAT报错 java.util.zip.ZipException: invalid LOC header (bad signature)
  7. 当使用easyui时,表单的onchange事件失效
  8. flash一个按钮控制动画_flutter闪屏过渡动画,闪光占位动画
  9. python树莓派 是什么_用树莓派和Python给你的植物浇水
  10. 哈维玛德学院 计算机,这些美国大学名气不高,却有最顶级的工程专业