Mysql的预编译和批处理
MySQL的预编译功能
预编译的好处
大家平时都使用过JDBC中的PreparedStatement接口,它有预编译功能。什么是预编译功能呢?它有什么好处呢?
当客户发送一条SQL语句给服务器后,服务器总是需要校验SQL语句的语法格式是否正确,然后把SQL语句编译成可执行的函数,最后才是执行SQL语句。其中校验语法,和编译所花的时间可能比执行SQL语句花的时间还要多。
如果我们需要执行多次insert语句,但只是每次插入的值不同,MySQL服务器也是需要每次都去校验SQL语句的语法格式,以及编译,这就浪费了太多的时间。如果使用预编译功能,那么只对SQL语句进行一次语法校验和编译,所以效率要高。
MySQL执行预编译
MySQL执行预编译分为如三步:
- 执行预编译语句,例如:prepare myfun from 'select * from t_book where bid=?'
- 设置变量,例如:set @str='b1'
- 执行语句,例如:execute myfun using @str
如果需要再次执行myfun,那么就不再需要第一步,即不需要再编译语句了:
- 设置变量,例如:set @str='b2'
- 执行语句,例如:execute myfun using @str
通过查看MySQL日志可以看到执行的过程:
使用Statement执行预编译
使用Statement执行预编译就是把上面的SQL语句执行一次。
|
Connection con = JdbcUtils.getConnection(); Statement stmt = con.createStatement(); stmt.executeUpdate("prepare myfun from 'select * from t_book where bid=?'"); stmt.executeUpdate("set @str='b1'"); ResultSet rs = stmt.executeQuery("execute myfun using @str"); while(rs.next()) { System.out.print(rs.getString(1) + ", "); System.out.print(rs.getString(2) + ", "); System.out.print(rs.getString(3) + ", "); System.out.println(rs.getString(4)); }
stmt.executeUpdate("set @str='b2'"); rs = stmt.executeQuery("execute myfun using @str");
while(rs.next()) { System.out.print(rs.getString(1) + ", "); System.out.print(rs.getString(2) + ", "); System.out.print(rs.getString(3) + ", "); System.out.println(rs.getString(4)); }
rs.close(); stmt.close(); con.close(); |
useServerPrepStmts参数
默认使用PreparedStatement是不能执行预编译的,这需要在url中给出useServerPrepStmts=true参数(MySQL Server 4.1之前的版本是不支持预编译的,而Connector/J在5.0.5以后的版本,默认是没有开启预编译功能的)。
例如:jdbc:mysql://localhost:3306/test?useServerPrepStmts=true
这样才能保证mysql驱动会先把SQL语句发送给服务器进行预编译,然后在执行executeQuery()时只是把参数发送给服务器。
|
Connection con = JdbcUtils.getConnection(); String sql = "select * from t_book where bid=?"; PreparedStatement pstmt = con.prepareStatement(sql);
pstmt.setString(1, "b1"); ResultSet rs = pstmt.executeQuery(); while(rs.next()) { System.out.print(rs.getString(1) + ", "); System.out.print(rs.getString(2) + ", "); System.out.print(rs.getString(3) + ", "); System.out.println(rs.getString(4)); }
pstmt.setString(1, "b2"); rs = pstmt.executeQuery(); while(rs.next()) { System.out.print(rs.getString(1) + ", "); System.out.print(rs.getString(2) + ", "); System.out.print(rs.getString(3) + ", "); System.out.println(rs.getString(4)); }
rs.close(); pstmt.close(); con.close(); |
cachePrepStmts参数
当使用不同的PreparedStatement对象来执行相同的SQL语句时,还是会出现编译两次的现象,这是因为驱动没有缓存编译后的函数key,导致二次编译。如果希望缓存编译后函数的key,那么就要设置cachePrepStmts参数为true。例如:
jdbc:mysql://localhost:3306/test?useServerPrepStmts=true&cachePrepStmts=true
|
Connection con = JdbcUtils.getConnection(); String sql = "select * from t_book where bid=?"; PreparedStatement pstmt = con.prepareStatement(sql);
pstmt.setString(1, "b1"); ResultSet rs = pstmt.executeQuery(); while(rs.next()) { System.out.print(rs.getString(1) + ", "); System.out.print(rs.getString(2) + ", "); System.out.print(rs.getString(3) + ", "); System.out.println(rs.getString(4)); }
pstmt = con.prepareStatement(sql); pstmt.setString(1, "b2"); rs = pstmt.executeQuery(); while(rs.next()) { System.out.print(rs.getString(1) + ", "); System.out.print(rs.getString(2) + ", "); System.out.print(rs.getString(3) + ", "); System.out.println(rs.getString(4)); }
rs.close(); pstmt.close(); con.close(); |
打开批处理
MySQL的批处理也需要通过参数来打开:rewriteBatchedStatements=true
Mysql的预编译和批处理的更多相关文章
- MySQL的预编译功能
1.预编译的好处 大家平时都使用过JDBC中的PreparedStatement接口,它有预编译功能.什么是预编译功能呢?它有什么好处呢? 当客户发送一条SQL语句给服务器后,服务器总是需要校验S ...
- MySQL开启预编译环境
Mysql是默认 没有开启预编译的,需要在配置中加上 jdbc:mysql://xxx.22.11.31:3306/dbname?useServerPrepStmts=true
- php mysql语句预编译(preparestatement)
预处理语句用于执行多个相同的 SQL 语句,并且执行效率更高. 预处理语句的工作原理如下: 预处理:创建 SQL 语句模板并发送到数据库.预留的值使用参数 "?" 标记 .例如: ...
- 浅谈 MySQL的预编译
之前的一篇 Mybatis中 #{}和${}的区别 中涉及到通过 SQL预编译和 #{} 传值 的方式防止SQL注入. 由此引发了想了解预编译的想法.那么什么是预编译那? 一.三个阶段: 词法和语义解 ...
- 预编译语句(Prepared Statements)介绍,以MySQL为例
背景 本文重点讲述MySQL中的预编译语句并从MySQL的Connector/J源码出发讲述其在Java语言中相关使用. 注意:文中的描述与结论基于MySQL 5.7.16以及Connect/J 5. ...
- mysql预编译
一.背景: 用Mybatis+mysql的架构做开发,大家都知道,Mybatis内置参数,形如#{xxx}的,均采用了sql预编译的形式,举例如下: <select id=”aaa” param ...
- CentOS下MySQL 5.7编译安装
CentOS下MySQL 5.7编译安装 文章目录 安装依赖包 下载相应源码包 添加mysql用户 预编译 编译安装 启动脚本,设置开机自启动 /etc/my.cnf,仅供参考 初始化数据库 设置 ...
- mybatis深入理解之 # 与 $ 区别以及 sql 预编译
mybatis 中使用 sqlMap 进行 sql 查询时,经常需要动态传递参数,例如我们需要根据用户的姓名来筛选用户时,sql 如下: select * from user where name = ...
- mybatis之 # 与 $ 区别以及 sql 预编译
mybatis 中使用 sqlMap 进行 sql 查询时,经常需要动态传递参数,例如我们需要根据用户的姓名来筛选用户时,sql 如下: select * from user where name = ...
随机推荐
- Win & Mac 系统之间U盘传递的U盘文件格式选取问题
Win & Mac 系统之间U盘传递的U盘文件格式选取问题 1. Win系统与Mac系统之间可以通过 exFat U盘文件系统传递 exFAT(Extended File Allocation ...
- hdu 5001 从任意点出发任意走d步不经过某点概率
http://acm.hdu.edu.cn/showproblem.php?pid=5001 给定n个点m条边的无向图问从任意点出发任意走d步,从不经过某个点的概率 本想先算路过每个点的概率然后用1减 ...
- fully delete project in Eclipse
选择你的项目(test)右击,选择delete——弹出框中勾选删除全部,如下如所示: 正常情况下,这样就能删除干净了,有时候你项目在运行,这时候你点击删除,那就会报下面的错误提示,虽然不会影响你其它项 ...
- 使用MTR命令诊断网络问题
以前在检查网络时习惯使用ping命令,因为ping命令非常简单,现在喜欢上了mtr命令,因为它真的很强大,但是对于刚刚接触这个命令的同学来说,理解起来就没有ping命令来的那么直观了,所以今天写一 ...
- C# 获取每一个像素点的RGB
int x, y; x = e.X; y = e.Y; Color pixel = MyImage.GetPixel(x, y); byte R = pixel.R; byte G = pixel.G ...
- LINQ to objects遇到的小坑
1.C#中LINQ to Objects中延迟查询的陷阱(其他类型的LINQ也基本一致) 之前在不了解LINQ延迟查询的时候,我使用下面的这种方式,将where语句的结果直接as为List<T& ...
- NetCore入门篇:(九)Net Core项目使用Session及用Redis做分布式
一.简介 1.因为Net Core默认是没有启动Session功能的,如果需要使用,需要通过代码开启. 2.本篇说明如果启用默认Session实现,即Session存到内存中. 3.本篇扩展说明如何用 ...
- 11-使用EF操作数据库
本篇博客对应视频讲解 回顾 上一篇教程我们讲了XML与JSON的序列化问题,我们可以看到序列化实际上也是不同形式的转换,我们通常要以字节流的形式做中转.同时我们也可以看到,对于序列化这种常见的需求,我 ...
- FFMPEG的函数翻译文档
https://blog.csdn.net/explorer_day/article/category/6289310/2 https://www.cnblogs.com/tocy/p/ffmpeg- ...
- Android - "已安装了存在签名冲突的同名数据包",解决方法!
错误提示:已安装了存在签名冲突的同名数据包. 解决方法:打开Android Studio,打开logcat,用usb线连接你出错的手机,识别出手机之后,在你的项目后面,点击“run”按钮,随后AS会提 ...