玩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. JavaScript 面向对象继承详解

    题记 由于js不像java那样是完全面向对象的语言,js是基于对象的,它没有类的概念.所以,要想实现继承,一般都是基于原型链的方式: 一.继承初探 大多数JavaScript的实现用 __proto_ ...

  2. 后缀数组(模板题) - 求最长公共子串 - poj 2774 Long Long Message

    Language: Default Long Long Message Time Limit: 4000MS   Memory Limit: 131072K Total Submissions: 21 ...

  3. Java开发中的23种设计模式(转)

    设计模式(Design Patterns) ——可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了 ...

  4. DIV嵌套垂直居中

    第一记住一点:父级相对定位,子级绝对定位 下面演示CSS样式: .父级DIV{ margin:0px auto; position:relative; border:2px solid #ff0000 ...

  5. ActiveReports 报表应用教程 (1)---Hello ActiveReports

    在开始专题内容之前,我们还是了解一下 ActiveReports 是一款什么产品:ActiveReports是一款在全球范围内应用非常广泛的报表控件,以提供.NET报表所需的全部报表设计功能领先于同类 ...

  6. idea使用maven搭建springmvc

    最近学着搭建springmvc,写此博客记录一下 idea版本:2016.3.1maven: apache-maven-3.3.9tomcat:apache-tomcat-8.5.8 1.New Pr ...

  7. 内核移植和文件系统制作(2):linux内核最小系统和initramfs文件系统

    linux内核最小系统,使用内核版本:https://www.kernel.org/pub/linux/kernel/v3.0/linux-3.8.1.tar.bz2 1,FL2440板子的基本硬件: ...

  8. UltraEdit打开UTF-8文件后显示中文乱码的问题

    左图是UE,默认的编码格式GBK.右图可以看出可修改成UTF-8编码.按钮位置是UE底部状态栏,图3显示怎么开关状态栏. >>>>>>>>>> ...

  9. Play Framework介绍:控制器层

    业务逻辑代码通常位于模型(model)层.客户端(比如浏览器)无法直接调用其中的代码,所以模型对象提供的功能,必须作为资源以URI方式暴露给外部. 客户端使用HTTP协议来操作这些资源,从而调用了内部 ...

  10. styleCop

    1styleCop安装 安装参考 2和VS集成 要和vs集成一定要在安装时把MSBuild files那个选项选中的,否则安装后是不会和VS集成集成的. 3styleCop使用 User Guide ...