GBase 8a数据库集群JDBC入库非常慢原因及解决方案(Datax同步数据到Gbase数据库也可用)
一、GBase 8a数据库集群JDBC入库方式如下:
1、insert方式,每次插入一行;
2、insert 方式,每次n行,批量提交;
3、输出成文件,load加载方式;
二、以上三种方式性能对比:
1、第一种,每次插入一行,性能最差,入库逻辑如下:
insert into XXX values ();
2、第二种,批量插入,比第一种方式插入速度提高了数倍,入库逻辑如下:
set autocommit=0;
insert into XXX values ();
insert into XXX values ();
insert into XXX values ();
….
commit;
set autocommit=1;
3、第三种,load加载方式(n条数据的值写到1条SQL里面,一次执行),比前面两种入库方式都快数倍以上,入库逻辑如下:
insert into XXX values (),(),(),();
三、本次验证使用了第二种和第三种入库方式对比:
1、insert 方式,每次n行,批量提交;
protected void doBatchInsert(Connection connection, List<Record> buffer)
throws SQLException {
PreparedStatement preparedStatement = null;
try {
connection.setAutoCommit(false);
preparedStatement = connection
.prepareStatement(this.writeRecordSql);
for (Record record : buffer) {
preparedStatement = fillPreparedStatement(
preparedStatement, record);
preparedStatement.addBatch();
}
preparedStatement.executeBatch();
connection.commit();
} catch (SQLException e) {
LOG.warn("回滚此次写入, 采用每次写入一行方式提交. 因为:" + e.getMessage());
connection.rollback();
doOneInsert(connection, buffer);
} catch (Exception e) {
throw DataXException.asDataXException(
DBUtilErrorCode.WRITE_DATA_ERROR, e);
} finally {
DBUtil.closeDBResources(preparedStatement, null);
}
}
运行结果还是非常慢(180W数据同步花了1181秒):
2、使用load加载方式(n条数据的值写到1条SQL里面,一次执行),解决方案如下:
(1)、结合第二种批量提交的代码逻辑,再修改JDBCUrl连接:
jdbc:gbase://192.168.88.99:5258/test?rewriteBatchedStatements=true
(2)、设置rewriteBatchedStatements=true参数后,GBase数据库的JDBC驱动自动将Batch Insert 方式的批量提交,自动重写成“ insert into XXX values (),(),(),(); ”的格式来执行以提高性能;
(3)、注意:如果数据存在了单引号等,没有提前转义(如转义成\’),会导致拼接出来的SQL语法错误;
(4)、运行结果(180W数据同步只用50秒),如下: