聊聊JDBC的executeBatch对⽐下不同数据库对JDBCbatch的实现细节
聊聊 JDBC 的 executeBatch || 对⽐下不同数据库对 JDBC batch 的实现细节 || 剖析下 Mysql 的参数 rewriteBatchedStatements || 剖析下 pg 的参数 reWriteBatchedInserts
⼤家好,我是明哥!
上篇博⽂,“对⽐下 datax 的 OceanBase/MYSQL 不同数据同步⽅案的效率差异 || 聊聊参数 rewriteBatchedStatements” 发表后,有⼩伙伴问到不同数据库对 JDBC 批量更新的实现细节,所以通过本⽚博⽂,我们系统看下 jdbc batch 相关知识。
1. JDBC batch 为什么能提⾼性能?
通过查看源码可知,JDBC1.2 引⼊了 Batch 功能,涉及的API主要有以下四个:
java.sql.Statement#addBatch下载mysql为什么下载不了
java.sql.PreparedStatement#addBatch
java.sql.Statement#executeBatch
java.sql.Statement#clearBatch
JDBC 引⼊上述 batch 功能的主要⽬的,是加快对客户端SQL的执⾏和响应速度,并进⽽提⾼数据库整体并发度,⽽ jdbc batch 能够提⾼对客户端SQL的执⾏和响应速度,其主要原理有:
减少了JDBC客户端和数据库服务器之间⽹络传输的开销:使⽤ batch 功能前,每提交⼀个SQL,都需要⼀次⽹络IO开销,且提交后需要等待服务端返回结果后,才能提交下⼀个SQL;⽽使⽤ batch 功能后,客户端的多个SQL是⼀起提交给服务器的,只涉及到⼀次⽹
络IO开销(single database round trip),其⽰意图如下:
当batch底层使⽤的是静态SQL并参数化执⾏时(JAVA中⼀般是使⽤类java.sql.PreparedStatement 来参数化执⾏静态SQL),数据库服务器可以只做⼀次解析:利⽤对参数化机制的⽀持,数据库服务器仅需要对 PreparedStatement 做⼀次解析(sql parse),即可传⼊不同参数执⾏该 batch 中所有的 SQL;
⽹上有个帖⼦,详细对⽐了不同场景下,不同数据库的插⼊和更新性能的差异,可以看出,ORACLE/PG/MYSQL 使⽤ batch 功能
后,性能都有了3-5被的提⾼:
2. JDBC batch 的使⽤场景和限制有哪些?
batch 功能对 statement 和 PreparedStatement 都有效,但为了避免 SQL 注⼊的风险,不推荐使⽤动态SQL,⽽是推荐使⽤静态SQL 和绑定变量(也就是使⽤ PreparedStatement 和 stored procedures);
从上述JDBC的API源码可以看出,batch 功能对所有SQL 都有效, 包括 SELECT/INSERT/UPDATE/DELETE,但由于使⽤ batch 功能后,返回值是 int[] 数组,不太⽅便获取
batch 底层每个sql的执⾏结果,所以⼤家⼀般不会对 SELECT 语句使⽤ batch 功能(毕竟select查询的⽬的是获得每个select语句的结果resultSet),⽽只会在⼤量 INSERT/UPDATE/DELETE 的场景下,尤其是⼤批量插⼊的场景下,使⽤ batch 功能,所以⼤家提到 batch时,常说“批量更新”;(数据仓库数据湖等涉及到数据集成和ETL的场景,经常会使⽤到批量插⼊);
另外需要注意的是,使⽤ batch 功能并不代表所有的 SQL 都在⼀个事务⾥:在 autocommit 模式下,after each statement you have created, the database will ensure that the result persists correctly before moving on to the next statement,if the nth sentence of a batch raises a constraint exception, all previously inserted rows will not be rollbacked;
3. 不同数据库对 JDBC batch 的实现有何异同?
由于 batch 功能是通过 JDBC API 定义的,是 JDBC 规范的⼀部分,所以所有实现了 JDBC 接⼝的数据库驱动,都需要实现这些接⼝,所以 mysql/oracle/pg/db2/sqlserver 等所有提供了 JDBC 接⼝的数据库,原则上都⽀持 jdbc batch 功能;
但不同数据库对这些接⼝的具体实现是不同的,所以其最终效果和使⽤细节会有些差异,甚⾄相同数据库驱动的不同版本,也可能会有所差异,所以⽤户在使⽤前,需要查看下对应数据库的说明,不能想当然地认为,某个数据驱动的参数,也同样使⽤于其它数据库驱动;
这⾥重点指出下,jdbc batch 相关参数,mysql 有参数 rewriteBatchedStatements,postgresql 有参数
reWriteBatchedInserts;
4. 详解 mysql 的参数 rewriteBatchedStatements
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论