测试mysql的sql语句预编译效果

玩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做硬解析:

 1 package exmysql;
 2
 3 import java.sql.Connection;
 4 import java.sql.DriverManager;
 5 import java.sql.ResultSet;
 6 import java.sql.SQLException;
 7 import java.sql.Statement;
 8 import java.util.Date;
 9
10 public class adddata {
11
12     private static long worker(){
13         Date begin = new Date();
14
15         String driver="com.mysql.jdbc.Driver";
16
17         String url="jdbc:mysql://172.16.2.7:3306/testdb";
18
19         Connection conn=null;
20         Statement stmt=null;
21         ResultSet rs=null;
22
23         try{
24             Class.forName(driver);
25             conn=DriverManager.getConnection(url,"dbaadmin","123456");
26             stmt=conn.createStatement();
27             String sql;
28             for (int i=1;i<=5000;i++){
29                 sql="select * from test1 where id="+i;
30                 rs=stmt.executeQuery(sql);
31             }
32         }
33         catch(SQLException | ClassNotFoundException e){
34             e.printStackTrace();
35         }
36
37         if(stmt!=null){
38             try{
39                 stmt.close();
40             }
41             catch(SQLException e){
42                 e.printStackTrace();
43             }
44         }
45
46         if(conn!=null){
47             try{
48                 conn.close();
49             }
50             catch(SQLException e){
51                 e.printStackTrace();
52             }
53         }
54
55         Date end = new Date();
56         return end.getTime()-begin.getTime();
57     }
58
59     public static void main(String[] args) {
60         // TODO Auto-generated method stub
61
62         long elapsed,average;
63         average=0;
64         for (int i=1;i<=10;i++){
65             elapsed=worker();
66             System.out.println("elapsed time(ms):"+elapsed);
67             average=average+elapsed;
68         }
69         System.out.println("average time(ms):"+average/10);
70     }
71
72 }

结果如下:

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预编译执行

 1 package exmysql;
 2
 3 import java.sql.*;
 4 import java.util.Date;
 5
 6 public class insert_data {
 7
 8     private static long worker(){
 9         Date begin = new Date();
10
11         String driver="com.mysql.jdbc.Driver";
12
13         String url="jdbc:mysql://172.16.2.7:3306/testdb";
14
15         Connection conn=null;
16         PreparedStatement pstm=null;
17         ResultSet rs=null;
18
19         try{
20             Class.forName(driver);
21             conn=DriverManager.getConnection(url,"dbaadmin","123456");
22             conn.setAutoCommit(false);
23             String sql="select * from test1 where id=?";
24             pstm=conn.prepareStatement(sql);
25             for(int i=1;i<=5000;i++){
26                 pstm.setInt(1, i);
27                 rs=pstm.executeQuery();
28             }
29             conn.commit();
30
31         }
32         catch(SQLException | ClassNotFoundException e){
33             e.printStackTrace();
34         }
35
36         if(pstm!=null){
37             try{
38                 pstm.close();
39             }
40             catch(SQLException e){
41                 e.printStackTrace();
42             }
43         }
44
45         if(conn!=null){
46             try{
47                 conn.close();
48             }
49             catch(SQLException e){
50                 e.printStackTrace();
51             }
52         }
53
54         Date end = new Date();
55         return end.getTime()-begin.getTime();
56     }
57
58     public static void main(String[] args) {
59         // TODO Auto-generated method stub
60
61         long elapsed,average;
62         average=0;
63         for (int i=1;i<=10;i++){
64             elapsed=worker();
65             System.out.println("elapsed time(ms):"+elapsed);
66             average=average+elapsed;
67         }
68         System.out.println("average time(ms):"+average/10);
69     }
70
71 }

结果如下:

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):14270

可以看出两种方式执行的结果几乎相同,不像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是没有性能上的提升的。

时间: 2024-10-05 21:22:33

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

MySQL查看SQL语句执行效率

Explain命令在解决数据库性能上是第一推荐使用命令,大部分的性能问题可以通过此命令来简单的解决,Explain可以用来查看 SQL 语句的执行效果,可以帮助选择更好的索引和优化查询语句,写出更好的优化语句. Explain语法:explain select - from - [where ...] 例如:explain select * from news; 输出: +----+-------------+-------+-------+-------------------+-------

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

1.查询条件的先后顺序 有多个查询条件时,要把效率高能更精确筛选记录的条件放在后边.因为MySQL解析sql语句是从后往前的(不知是否准确). 例: select a.*,b.* from UsrInf a,OrgInf b where LogNam='njnydx9' and b.OrgId=a.blnorg SQL语句从后往前解析,把LogNam='njnydx9'换到后边,避免了更多结果集的连接,提高了执行效率 2.in的效率问题 看网上都说in相当于多个条件的or.实际测试后发现in的执

mysql数据库sql语句调优 、

mysql数据库sql语句调优 . 索引设计原则: 索引列一般为where子句中的列或连接字句中的列 尽量不对基数小的列做索引,如性别列 尽可能使用短索引:如果对字符列索引尽量指定最小长度. (short Keys are better,Integer best) create index cityname on city(city(10)); 复合索引前缀特性,索引的顺序很重要. key(a,b,c)联合索引: 可以走索引的组合:key(a),key(a,b ),key(a,b,c) 下列索引

mysql优化sql语句

mysql优化sql语句 常见误区 www.2cto.com 误区1: count(1)和count(primary_key) 优于 count(*) 很多人为了统计记录条数,就使用 count(1) 和 count(primary_key) 而不是 count(*) ,他们认为这样性能更好, 其实这是一个误区.对于有些场景,这样做可能性能会更差,应为数据库对 count(*) 计数操作做了一些特别的优化. 误区2: count(column) 和 count(*) 是一样的 这个误区甚至在很多

Mysql常用sql语句(一)- 操作数据库

21篇测试必备的Mysql常用sql语句,每天敲一篇,每次敲三遍,每月一循环,全都可记住!! https://www.cnblogs.com/poloyy/category/1683347.html 需要注意,创建数据库和创建表的语句博文都在前面哦,整个系列都是相互关联的哈,需要用到前面创建的数据库和表哦 前言 针对数据库的操作语句叫做数据定义语言(DDL)   数据库有哪些操作呢? 创建数据库 查询数据库 修改数据库 删除数据库 选择数据库 简称“增删改查“,点击右边目录即可跳转哦! ----

Mysql常用sql语句(二)- 操作数据表

21篇测试必备的Mysql常用sql语句,每天敲一篇,每次敲三遍,每月一循环,全都可记住!! https://www.cnblogs.com/poloyy/category/1683347.html 需要注意,创建数据库和创建表的语句博文都在前面哦 整个系列都是相互关联的哈,需要用到前面创建的数据库和表哦(系列博文第一篇和第二篇) 前言 针对数据表的操作语句叫做数据定义语言(DDL)   数据表有哪些操作? 创建数据表 查看表结构 查看数据表的创建语句 复制数据表 修改数据表 删除数据表 简称“

Orecle Mysql 基本sql语句DDL & DML 介绍与总结 by 冰琉璃

先给大家普及一下安装mysql的简易方法:yum yum search mysql (查找关于mysql的内容) 找到后需要安装3个内容 mysql.i386 mysql-server.i386 mysql-devel.i386 安装过后 service mysqld start (启动mysql服务) 进入mysql mysql -h -u root -p 密码直接回车 开始密码为默然:以后可以在mysql里面改密码或者创建账号等操作 Mysql的sql语句大致分为4种  DDL (定义语句)

Effective MySQL之SQL语句最优化

推荐本SQL优化的书<Effective MySQL之SQL语句最优化>. 主要讲解:如何去分析SQL的性能.索引的原理.如何创建合适的索引.如何去分析线上系统的性能瓶颈. 另外还介绍了几个辅助工具: mysqldumpslow 来分析慢查询日志: Google开源的mysql-slow-query-log-parser 分析慢查询日志: 应用程序中使用MySQL Proxy来收集SQL语句.QEP.查询执行时间: 开源Maatkit检查数据库中的重复索引: Google的MySQL补丁,引入

MySQL批处理SQL语句

MySQL 支持批处理的模式执行一批SQL语句,下面的例子就是实验MySQL如何在windows下批处理执行SQL语句. create table test(id int,name varchar(20)); insert into test values(1,'watson'); batchfile.txt里包含下面的一些SQL 语句,此文件放在windows系统的c:/batchmysql/batchfile.txt insert into test select * from test;