玩Oracle的都比较关注shared pool,特别是library cache,在使用了绑定变量(预编译sql)之后确实能得到很大的性能提升。现在在转Mysql之后特别是innodb很多东西都还能和Oracle对得上号的,就像innodb_buffer_pool_size类似于Oracle的database buffer cache,innodb_log_buffer_size类似于redo log buffer,但是innodb_additional_mem_pool_size仅仅类似于shared pool的Data dictionary cache,似乎还缺少和library cache相对应的东西。那就有一个问题了,在Mysql里面使用预编译的sql还会有性能提升吗?

这里我用Java的jdbc做了一下测试,分别用Statement和PreparedStatement执行1000个sql,并运行10次

1.使用Statement做硬解析:

 package exmysql;

 import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Date; public class adddata { private static long worker(){
Date begin = new Date(); String driver="com.mysql.jdbc.Driver"; String url="jdbc:mysql://172.16.2.7:3306/testdb"; Connection conn=null;
Statement stmt=null;
ResultSet rs=null; try{
Class.forName(driver);
conn=DriverManager.getConnection(url,"dbaadmin","123456");
stmt=conn.createStatement();
String sql;
for (int i=1;i<=5000;i++){
sql="select * from test1 where id="+i;
rs=stmt.executeQuery(sql);
}
}
catch(SQLException | ClassNotFoundException e){
e.printStackTrace();
} if(stmt!=null){
try{
stmt.close();
}
catch(SQLException e){
e.printStackTrace();
}
} if(conn!=null){
try{
conn.close();
}
catch(SQLException e){
e.printStackTrace();
}
} Date end = new Date();
return end.getTime()-begin.getTime();
} public static void main(String[] args) {
// TODO Auto-generated method stub long elapsed,average;
average=0;
for (int i=1;i<=10;i++){
elapsed=worker();
System.out.println("elapsed time(ms):"+elapsed);
average=average+elapsed;
}
System.out.println("average time(ms):"+average/10);
} }

结果如下:

elapsed time(ms):24652
elapsed time(ms):13380
elapsed time(ms):13250
elapsed time(ms):13877
elapsed time(ms):13275
elapsed time(ms):13193
elapsed time(ms):19022
elapsed time(ms):13558
elapsed time(ms):14138
elapsed time(ms):13364
average time(ms):15170

2.同样的sql用PreparedStatement预编译执行

 package exmysql;

 import java.sql.*;
import java.util.Date; public class insert_data { private static long worker(){
Date begin = new Date(); String driver="com.mysql.jdbc.Driver"; String url="jdbc:mysql://172.16.2.7:3306/testdb"; Connection conn=null;
PreparedStatement pstm=null;
ResultSet rs=null; try{
Class.forName(driver);
conn=DriverManager.getConnection(url,"dbaadmin","123456");
String sql="select * from test1 where id=?";
pstm=conn.prepareStatement(sql);
for(int i=1;i<=5000;i++){
pstm.setInt(1, i);
rs=pstm.executeQuery();
} }
catch(SQLException | ClassNotFoundException e){
e.printStackTrace();
} if(pstm!=null){
try{
pstm.close();
}
catch(SQLException e){
e.printStackTrace();
}
} if(conn!=null){
try{
conn.close();
}
catch(SQLException e){
e.printStackTrace();
}
} Date end = new Date();
return end.getTime()-begin.getTime();
} public static void main(String[] args) {
// TODO Auto-generated method stub long elapsed,average;
average=0;
for (int i=1;i<=10;i++){
elapsed=worker();
System.out.println("elapsed time(ms):"+elapsed);
average=average+elapsed;
}
System.out.println("average time(ms):"+average/10);
} }

结果如下:

elapsed time(ms):14773
elapsed time(ms):16352
elapsed time(ms):14797
elapsed time(ms):15800
elapsed time(ms):12069
elapsed time(ms):14953
elapsed time(ms):13238
elapsed time(ms):12366
elapsed time(ms):15263
elapsed time(ms):13089
average time(ms):

可以看出两种方式执行的结果几乎相同,不像Oracle差距那么大。而且就算是用PreparedStatement的方式,在Mysql数据库端抓出来的sql语句也不是以变量id=?的形式出现的,而是实际的数值。后来在网上看到在连接字符串上加上useServerPrepStmts=true可以实现真正的预编译

        String url="jdbc:mysql://172.16.2.7:3306/testdb";
url=url+"?useServerPrepStmts=true";

加上这段后可以在数据库端可以看到明确的结果:

mysql> show global status like 'Com_stmt_prepare';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| Com_stmt_prepare | 11 |
+------------------+-------+
1 row in set (0.00 sec)

但是实际的运行结果和上面几乎一样,性能上也没有任何的提升。由此可以推断出Mysql由于缺少类似于Oracle的library cache的部件,因此采用预编译方式执行sql是没有性能上的提升的。

测试mysql的sql语句预编译效果的更多相关文章

  1. mysql 常用 sql 语句 - 快速查询

    Mysql 常用 sql 语句 - 快速查询 1.mysql 基础 1.1 mysql 交互         1.1.1 mysql 连接             mysql.exe -hPup    ...

  2. Mysql常用sql语句(16)- inner join 内连接

    测试必备的Mysql常用sql语句系列 https://www.cnblogs.com/poloyy/category/1683347.html 前言 利用条件表达式来消除交叉连接(cross joi ...

  3. Mysql常用sql语句(18)- union 全连接

    测试必备的Mysql常用sql语句系列 https://www.cnblogs.com/poloyy/category/1683347.html 前言 其实Mysql并没有全连接,Oracle才有全连 ...

  4. MySQL 数据库SQL语句——高阶版本2

    MySQL 数据库SQL语句--高阶版本2 实验准备 数据库表配置: mysql -uroot -p show databases; create database train_ticket; use ...

  5. 29.MySQL高级SQL语句

    MySQL高级SQL语句 目录 MySQL高级SQL语句 创建两个表 SELECT DISTINCT WHERE AND OR IN BETWEEN 通配符 LIKE ORDER BY 函数 数学函数 ...

  6. Mysql 常用 SQL 语句集锦

    Mysql 常用 SQL 语句集锦 基础篇 //查询时间,友好提示 $sql = "select date_format(create_time, '%Y-%m-%d') as day fr ...

  7. Mysql 常用 SQL 语句集锦 转载(https://gold.xitu.io/post/584e7b298d6d81005456eb53)

    Mysql 常用 SQL 语句集锦 基础篇 //查询时间,友好提示 $sql = "select date_format(create_time, '%Y-%m-%d') as day fr ...

  8. MySQL数据库sql语句的一些简单优化

    1.查询条件的先后顺序 有多个查询条件时,要把效率高能更精确筛选记录的条件放在后边.因为MySQL解析sql语句是从后往前的(不知是否准确). 例: select a.*,b.* from UsrIn ...

  9. MySQL数据库SQL语句基本操作

    一.用户管理: 创建用户: create user '用户名'@'IP地址' identified by '密码'; 删除用户: drop user '用户名'@'IP地址'; 修改用户: renam ...

随机推荐

  1. 【第三课】ANR和OOM——贪快和贪多的后果(下)

    Out of Mana,法力耗尽. 内存就像法力,耗尽了就什么都不能做了.有时候一个应用程序占用了太大的内存,超过了Android系统为你规定的限制,那么系统就会干掉你,以保证其他app有足够的内存. ...

  2. 解决tomcat was unable to start within问题

    这个问题可能大家都熟悉,以前碰到这个问题,重新启动一次eclipse就好了,随着我的一个项目的增大,我发现这种情况越来越多,到底是怎么回事? 出现这个情况的原因有两个,要么是你的数据库连接connec ...

  3. Node.js爬虫数据抓取 -- 问题总结

    一  返回的信息提示  Something went wrong  request模块请求出现未知错误 其中,所用代码如下(无User-Agent部分) 问题多次派查无果,包括: 1:postman请 ...

  4. macbook装双系统多分区其实很简单,你只要把macbook当作一台普通pc就可以了!

    macbook装双系统多分区其实很简单,你只要把macbook当作一台普通pc就可以了! 不用理会苹果官网的警告,苹果官网警告你只能用bootcamp安装且不能多分区,把人吓得不轻.其实不用过多担心, ...

  5. ToDoList:一款非常优秀的任务管理软件 —— 工具类

    ToDoList是一款非常优秀的任务管理软件,用户可以方便地组织和安排计划.这是一个开源的项目,很多细节都考虑到了,推荐大家使用~ ToDoList 帮你把要做的事情列出来,一项一项,类似思维导图. ...

  6. 【BZOJ 4326】【NOIP2015】运输计划

    http://www.lydsy.com/JudgeOnline/problem.php?id=4326 题目描述 公元2044年,人类进入了宇宙纪元. 国有个星球,还有条双向航道,每条航道建立在两个 ...

  7. ahjesus约束方法或属性的调用方

    class Program { static void Main(string[] args) { test(); run(); Console.ReadKey(); } static void ru ...

  8. Android5.0新特性——全新的动画(animation)

    全新的动画 在Material Design设计中,为用户与app交互反馈他们的动作行为和提供了视觉上的连贯性.Material主题为控件和Activity的过渡提供了一些默认的动画,在android ...

  9. JavaScript If...Else、Switch、For、While、Break、Continue语句

    一,JavaScript If...Else 语句 条件语句 通常在写代码时,您总是需要为不同的决定来执行不同的动作.您可以在代码中使用条件语句来完成该任务. 在 JavaScript 中,我们可使用 ...

  10. Matlab2014a 提示未找到支持的编译器或 SDK的解决方法

    最近在写论文,用到了matlab版本的libsvm,在混合编译的时候遇到的一点小问题. 我电脑上装的是matlab2014a,window7 64位 >> mbuild -setup 错误 ...