IN子句效率中的preparedstatement设置值

时间:2014-11-12 11:55:16

标签: java sql prepared-statement

代码应该与数据库无关,所以我使用普通的sql。

我的查询可以在运行时更改,表示table1已更改为table2。 但是我们假设对于table1查询我必须更新插槽为50的2000条记录,这意味着只要处理50条记录就会提交。

我有两种方法可以在sql语句的IN子句中设置值。 我想知道下面哪个代码更有效(priority is optimization and maintainability is secondary)?

PreparedStatement preparedStatement = sqlObj.prepareStatement(
    "UPDATE table1 column1=? WHERE table_id IN (" + StringUtils.repeat("?,", paramArray.length-1)+ "?)");
preparedStatement.setInt(1, 0);
for(int idx = 0; idx < paramArray.length; idx++) {
    preparedStatement.setInt(idx+2, paramArray[idx]);
}
preparedStatement.executeQuery();

或者

PreparedStatement preparedStatement = sqlObj.prepareStatement(
    "UPDATE table1 column1=? WHERE table_id IN (?)");
for(int idx = 0; idx < paramArray.length; idx++) {
    preparedStatement.setInt(1, 0);
    preparedStatement.setInt(2, paramArray[idx]);

    preparedStatement.addBatch();
}
preparedStatement.executeBatch();

修改 让我们说param.length is 50和整个代码exectutes 40 times,即处理2000 records

所以在第一种情况下,它会追加50?然后为它们设置变量以进行一次更新查询,在第二种情况下,它将创建50个更新查询批次。

3 个答案:

答案 0 :(得分:0)

似乎在第二个你根本不需要IN,你可以使用WHERE table_id =?因为你每次都设置1个值。 在这种情况下,第二个会更快,因为您将使用批处理。

拜托,请看 Why are batch inserts/updates faster? How do batch updates work?

如果您使用的是Oracle,您还可以执行类似

的操作
create or replace TYPE "NUMBER_ARRAY" IS TABLE OF NUMBER(18,0);   

和Java代码

PreparedStatement preparedStatement = sqlObj.prepareStatement(
"UPDATE table1 column1=? WHERE table_id IN (SELECT column_value FROM TABLE (CAST(? AS number_array)))");    
JdbcUtils.setArray(2, tableIds.toArray(new Long[tableIds.size()]), ps);    

答案 1 :(得分:0)

第一种方法导致为每次调用重新创建准备好的语句,因此不需要准备好的语句。第二个可以预编译并重复使用。这是主要区别:您的第二种方法允许您重用查询对象并省略查询解析。 编辑:对不起,读得太快了。显然绑定许多参数比绑定一个参数效率低。

答案 2 :(得分:0)

如果这只是一个好奇的问题,我会说它更多地取决于数据库而不是准备好的声明。数据库操作比移动一些字节更昂贵。

如果你问这个问题是因为你想让你的应用程序更快,我不得不问这个更新是否真的是性能瓶颈。你有没有测量过它?

如果这不是性能瓶颈,并且您希望优化以防万一:不要。拥有可维护代码比优化非关键代码更重要。使用复杂性最低且最容易理解的变体:变体2。