ENABLE_BULK_LOAD
那里的任何人都可以通过 JConnect(带有)向 Sybase ASE提供批量插入的示例吗?
我搜索了互联网并没有找到任何东西。
ENABLE_BULK_LOAD
那里的任何人都可以通过 JConnect(带有)向 Sybase ASE提供批量插入的示例吗?
我搜索了互联网并没有找到任何东西。
我与 Sybase 的一位工程师取得了联系,他们为我提供了一个代码示例。所以,我要回答我自己的问题。
基本上这里是一个概要,因为代码示例非常大......这假设有很多预先初始化的变量,否则它将是几百行。任何有兴趣的人都应该得到这个想法。这可以在完美的世界中每秒产生多达 22K 的插入(无论如何根据 Sybase)。
SybDriver sybDriver = (SybDriver) Class.forName("com.sybase.jdbc3.jdbc.SybDriver").newInstance();
sybDriver.setVersion(com.sybase.jdbcx.SybDriver.VERSION_6);
DriverManager.registerDriver(sybDriver);
//DBProps (after including normal login/password etc.
props.put("ENABLE_BULK_LOAD","true");
//open connection here for sybDriver
dbConn.setAutoCommit(false);
String SQLString = "insert into batch_inserts (row_id, colname1, colname2)\n values (?,?,?) \n";
PreparedStatement pstmt;
try
{
pstmt = dbConn.prepareStatement(SQLString);
}
catch (SQLException sqle)
{
displaySQLEx("Couldn't prepare statement",sqle);
return;
}
for (String[] val : valuesToInsert)
{
pstmt.setString(1, val[0]); //row_id varchar(30)
pstmt.setString(2, val[1]);//logical_server varchar(30)
pstmt.setString(3, val[2]); //client_host varchar(30)
try
{
pstmt.addBatch();
}
catch (SQLException sqle)
{
displaySQLEx("Failed to build batch",sqle);
break;
}
}
try {
pstmt.executeBatch();
dbConn.commit();
pstmt.close();
} catch (SQLException sqle) {
//handle
}
try {
if (dbConn != null)
dbConn.close();
} catch (Exception e) {
//handle
}
在遵循您的大部分建议之后,我们没有看到与简单地创建一个巨大的字符串并将其与周围事务分批发送 ~100-1000 行相比有任何改进。我们解决了:*大字符串方法 [500 批次中的 5000 行]:1716 毫秒 = ~2914 行/秒。(这是狗屎!)。
我们的数据库位于具有一个 CPU(下面为 i7)的虚拟主机上,表模式为:
CREATE TABLE
archive_account_transactions
(
account_transaction_id INT,
entered_by INT,
account_id INT,
transaction_type_id INT,
DATE DATETIME,
product_id INT,
amount float,
contract_id INT NULL,
note CHAR(255) NULL
)
在 account_transaction_id (pk)、account_id、DATE、contract_id 上有四个索引。
只是想我会先发表一些评论,我们正在使用以下方法进行连接:
jdbc:sybase:Tds:40.1.1.2:5000/ikp?EnableBatchWorkaround=true;ENABLE_BULK_LOAD=true
我们也尝试了上面描述的 .addBatch 语法,但它比仅使用 java StringBuilder 在 sql 中手动构建批处理然后在一个执行语句中推送它稍微慢一些。删除插入语句中的列名给我们带来了惊人的性能提升,这似乎是唯一真正影响性能的东西。由于 Enable_bulk_load 参数似乎根本没有影响它,EnableBatchWorkaround 也没有,我们也尝试了 DYNAMIC_PREPARE=false 这听起来很有希望,但似乎也没有做任何事情。
让这些参数真正发挥作用的任何帮助都会很棒!换句话说,有没有我们可以运行的测试来验证它们是否有效?我仍然相信这种性能并没有接近 sybase 的界限,因为开箱即用的 mysql 使用相同的“大字符串方法”和相同的模式每秒可以处理 16,000 行。
干杯棒
为了让 Chris Kannon 提供的示例正常工作,请不要忘记先禁用自动提交模式:
dbConn.setAutoCommit(false);
并将以下行放在 dbConn.commit() 之前:
pstmt.executeBatch();
否则,这种技术只会减慢插入速度。
不知道如何在 Java 中执行此操作,但您可以使用 LOAD TABLE SQL 语句批量加载文本文件。我们通过 JConnect 使用 Sybase ASA 做到了这一点。
支持批量更新
批量更新允许一个 Statement 对象将多个更新命令作为一个单元(批次)提交到底层数据库一起处理。
注意:要使用批量更新,您必须刷新 jConnect 安装目录下 sp 目录中的 SQL 脚本。章节
有关将批更新与 Statement、PreparedStatement 和 CallableStatement 一起使用的示例,请参见 sample (jConnect 4.x) 和 sample2 (jConnect 5.x) 子目录中的 BatchUpdates.java 。jConnect 还支持批量动态 PreparedStatements。
参考:
http://download.sybase.com/pdfdocs/jcg0420e/prjdbc.pdf
.
其他批量更新资源
http://java.sun.com/j2se/1.3/docs/guide/jdbc/spec2/jdbc2.1.frame6.html