测试mysql的sql语句预编译效果
2016-09-09 11:20
225 查看
手动迁移原创博客,原文发表在http://www.cnblogs.com/paololiu/p/5070737.html
玩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做硬解析:
结果如下:
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预编译执行
结果如下:
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可以实现真正的预编译
加上这段后可以在数据库端可以看到明确的结果:
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是没有性能上的提升的。
玩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):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是没有性能上的提升的。
相关文章推荐
- MySQL SQL常用语句自我测试练习
- 使用MySql数据库基准压力测试工具mysqlslap重放sql语句
- MySQL_SQL常用语句自我测试练习-2
- MySQL查看SQL语句执行效率和mysql几种性能测试的工具
- 使用sql语句制造测试数据数量(Mysql)
- 在Eclipse中测试MySQL-JDBC(9)statement 批处理(同时执行多条sql语句)
- mysql测试数据库employees一些sql语句
- PHP MYSQL精确测试SQL语句执行时间
- Mysql执行大文件sql语句 -- 未测试
- 在jmeter测试mysql中如何一次运行多条sql语句
- MySQL查看SQL语句执行效率和mysql几种性能测试的工具
- 查看mysql中database占用磁盘空间的大小SQL语句【测试通过】
- 在jmeter测试mysql中如何一次运行多条sql语句
- 在jmeter测试mysql中如何一次运行多条sql语句
- loadrunner测试mysql中某个sql语句或存储过程的性能分享
- MYSQL5.0 脚本测试笔记【复制表结构和数据SQL语句】
- 使用Jmeter对Mysql进行压力测试无法执行多条sql语句问题
- 在Eclipse中测试MySQL-JDBC(10)preparestatement批处理(同时执行多条sql语句)
- 关于sql语句的执行效率测试
- Oracle、SQL Server、Access利用SQL语句进行高效果分页