原文:http://blog.csdn.net/yzsind/article/details/7266281
参考:http://singleant.iteye.com/blog/1298837
用习惯了oracle,学习mysql,想测试一下mysql绑定变量的效果。以前看网上介绍大部份都说mysql没有sql共享池的概念,所以也不存在sql预解析或绑定变量的说法。
今天测试了一下(通过网络抓包、查看服务器端sql日志及分析源码等方法),发现mysql还是有sql预解析的实现。
服务器端是mysql 5.1.58(win32),用jdbc(5.1.18)做客户端,默认的连接方式是不会有sql预解析效果,即使我们用 PreparedStatement对象也差不多,它只是把SQL和变量拼接成一个完整的SQL发送给服务器,如下代码:
PreparedStatement pstmt = conn.prepareStatement("select * from t1 where c1=?"); pstmt.setString(1, "abc"); pstmt.execute();
实际上不会有预解析的过程,而是经过简单的拼接,把如下SQL发送给服务器
select * from t1 where c1= 'abc'
要实现预解析的效果,我们必须设置jdbc Connection的参数useServerPrepStmts=true,再使用PreparedStatement后就OK了,创建 PreparedStatement时客户端先把"select * from t1 where c1=?"发送到服务器端预解析,execute时只是把变量传送到服务器执行。
mysql服务器的sql语句缓存可以通过状态变量Prepared_stmt_count查看
mysql> show status like 'Prepared_stmt_count'; +---------------------+-------+ | Variable_name | Value | +---------------------+-------+ | Prepared_stmt_count | 1 | +---------------------+-------+ 1 row in set
不过mysql的sql语句缓存与oracle有很大不同,它是会话语句级的,不是全局共享,当会话断开或 PreparedStatement.close后这个缓存就没有了。我们需要设置Connection的参数cachePrepStmts=true把 PreparedStatement缓存起来,prepStmtCacheSize=xxx来设置每个会话缓存语句的最大数量(很多连接池也有类似的功 能)。
OK,已经知道如何启用预解析了,想看看启用与不启用预解析性能有多少差别,会不会也像oracle那么明显呢?经过简单的测试,发现当没有 PreparedStatement缓存(cachePrepStmts=false)时,打开预解析性能下降很多, 当有PreparedStatement缓存(cachePrepStmts=true)时,两者性能基本一样。这个结果让人很失望,个人分析有几个原 因:
启用预解析但没有PreparedStatement缓存时,每次创建PreparedStatement都需要解析一次,execute时又需要交互一 次,而预解析的SQL在PreparedStatement.close又不能重用,所以性能反而更差。
当有PreparedStatement缓存时,预解析的SQL文本缓存在服务器端,但是并不会像oracle一样缓存执行计划,所以每次execute 时都需要解析SQL和生成执行计划,因此只是减少了每次execute传输SQL的文本大小,性能差别不大。
注: 如果SQL语法错误,那么服务器端预解析会出错,但jdbc收到预解析出错的信息后并不提示出错,而是将取消本条语句预解析的状态,execute时直接 把SQL接装发送给服务器,mysql jdbc在PreparedStatement构造函数中代码如下,其中返回ServerPreparedStatement类表示使用了绑定变量,返回 PreparedStatement表示未使用绑定变量:
try { pStmt = ServerPreparedStatement.getInstance(getLoadBalanceSafeProxy(), nativeSql, this.database, resultSetType, resultSetConcurrency); pStmt.setResultSetType(resultSetType); pStmt.setResultSetConcurrency(resultSetConcurrency); } catch (SQLException sqlEx) { // Punt, if necessary if (getEmulateUnsupportedPstmts()) { pStmt = (PreparedStatement) clientPrepareStatement(nativeSql, resultSetType, resultSetConcurrency, false); } else { throw sqlEx; } }
经过上面分析,个人认为不需要打开SQL预解析的效果,PreparedStatement对象还是尽量使用,因为虽然不能提升性能,但可以避免SQL注入安全问题 。
相关推荐
本教程将详细介绍如何使用JDBC连接MySQL数据库,实现数据的增、删、改、查操作,这对于初学者来说是一个重要的学习起点。 首先,确保你的系统中已经安装了MySQL数据库并创建了一个数据库实例。接下来,你需要获取...
本示例将讲解如何使用Java JDBC连接MySQL数据库,这对于任何Java开发者来说都是基础且重要的技能。 首先,我们需要在项目中引入MySQL的JDBC驱动。在Maven项目中,可以在pom.xml文件中添加以下依赖: ```xml ...
本教程将深入探讨如何使用JDBC连接MySQL数据库并实现增、删、改、查(CRUD)操作。首先,我们需要确保已经安装了MySQL数据库,并且在系统中配置了相应的驱动。 1. **引入MySQL JDBC驱动** 要使用JDBC与MySQL通信,...
本案例将探讨如何使用JDBC连接MySQL数据库,并通过实际的代码示例讲解整个过程。我们将涉及以下知识点: 1. **JDBC驱动注册**: 在Java中,连接MySQL数据库首先需要加载并注册JDBC驱动。MySQL的JDBC驱动类是`...
本教程将专注于使用Java的JDBC(Java Database Connectivity)接口来实现MySQL数据库之间的迁移,以及分表数据的迁移。 首先,JDBC是Java语言访问数据库的标准API,它允许Java程序与各种数据库进行交互,包括MySQL...
总结来说,JDBC是Java与MySQL数据库交互的重要桥梁,通过规范化的API,简化了数据库编程,同时提供了良好的性能和平台兼容性。理解和熟练使用JDBC是每个Java开发者必备的技能之一。在实际项目中,开发者应根据需求...
### JDBC连接MySQL数据库关键的四个步骤 在现代软件开发中,Java作为一种广泛使用的编程语言,其与数据库的交互是必不可少的一部分。JDBC(Java Database Connectivity)作为Java平台上的标准数据库访问接口,允许...
在本案例中,"JDBC连接MySQL数据库8.0.13的驱动包" 提供了连接MySQL 8.0.13版本数据库所需的Java驱动程序。MySQL是一种开源、免费的关系型数据库管理系统,广泛应用于Web应用、企业内部系统以及各类数据存储需求。 ...
标题“JDBC-MySQL数据库驱动”指的是Java Database Connectivity (JDBC) 驱动程序,这是Java编程语言与MySQL关系型数据库管理系统之间通信的桥梁。描述中同样提到了JDBC-MySQL数据库驱动,进一步确认了主题是关于...
在Java编程中,纯JDBC(Java Database Connectivity)连接MySQL数据库是一种基础且直接的方式,用于实现Java应用程序与MySQL数据库之间的交互。下面将详细解析标题和描述中涉及的知识点,并扩展相关的内容。 1. **...
在本主题中,我们将深入探讨如何使用JDBC连接MySQL数据库。 首先,理解JDBC的基础概念至关重要。JDBC提供了一组接口和类,它们定义了与数据库进行通信的通用方法。这些接口包括DriverManager、Connection、...
本示例是关于如何使用Java JDBC与MySQL数据库进行交互的一个简单教程,适合初学者入门学习。 1. **JDBC基础知识** - **JDBC驱动**:在Java中,与数据库通信需要JDBC驱动。MySQL提供四种类型的JDBC驱动,分别是Type...
**JDBC操作MySQL数据库基础教程** 在Java编程中,JDBC(Java Database Connectivity)是用于与各种数据库进行交互的一套标准API。它允许Java应用程序连接并执行SQL语句,实现数据的CRUD(Create、Read、Update、...
直接使用JDBC访问MySQL数据库为Android应用程序提供了更多的灵活性和控制权,但同时也带来了额外的安全性和性能方面的挑战。开发者在选择这种方案时需要仔细评估其适用性,并采取相应的安全措施和技术优化,以确保...
本教程将通过一个具体的实例,讲解如何使用JDBC连接MySQL数据库。 首先,我们需要确保已经安装了MySQL数据库并创建了一个数据库和表。在MyEclipse环境中,可以通过数据源配置来管理数据库连接。MyEclipse是集成开发...
本示例是关于如何使用JDBC连接MySQL数据库的一个实践教程,涵盖了数据库连接、数据操作以及大文本和图片的存储。 首先,我们需要了解JDBC的基本流程,包括加载驱动、建立连接、创建Statement或PreparedStatement...
使用JDBC连接MySQL数据库的步骤通常包括:加载驱动、建立连接、创建Statement或PreparedStatement对象、执行SQL、处理结果集以及关闭连接。以下是一个基本示例: ```java Class.forName("com.mysql.jdbc.Driver")...
本项目"JavaWeb-JDBC连接MySql数据库"提供了一个简单的示例,展示了如何使用JDBC来执行SQL查询操作。 首先,我们需要了解JDBC的基本组件和流程。JDBC包含四个主要部分:驱动程序管理器、数据库驱动程序、JDBC API和...