IN子句效率中的preparedstatement设置值
Posted
技术标签:
【中文标题】IN子句效率中的preparedstatement设置值【英文标题】:preparedstatement setting values in IN clause efficiency 【发布时间】:2015-01-09 06:29:42 【问题描述】:代码应该是独立于数据库的,所以我使用的是普通的 sql。
我的查询可以在运行时更改,例如 table1 更改为 table2。 但是假设对于 table1 查询,我必须更新 2000 条记录,其中插槽为 50,这意味着一旦处理了 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 个更新查询。
【问题讨论】:
如果您只调用一次或很少调用代码,那么第一个。否则,这取决于您进行相同更新的频率、每次包含多少参数以及数据库的语句缓存。 我已经更新了我的问题。 【参考方案1】:似乎第二次你根本不需要 IN,你可以使用 WHERE table_id = ?因为您每次设置 1 个值。 在这种情况下,第二个会更快,因为您将使用 Batch。
请看 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);
【讨论】:
提问者正在请求数据库独立代码。 @Peter,在我提到数据库独立性之前已经给出了答案。 啊,好吧,所以@prsmax:对不起:)【参考方案2】:第一种方法导致为每次调用重新创建准备好的语句,因此不需要准备好的语句。第二个可以预编译和重用。这是主要区别:您的第二种方法允许您重用查询对象并省略查询解析。 编辑:对不起,读得太快了。绑定多个参数显然比绑定一个参数效率低。
【讨论】:
你能澄清一下这个“所以there is no need for a prepared statement
”,我应该用什么来代替准备好的声明。
不,我只是读得快而且不完整。请参阅“已编辑” - 响应的一部分。您的第二种方法确实取决于您要绑定的只有两个参数,因此您的语句之间的主要区别在于批处理。这并不是真正需要的,因为您只发送一个命令(sql 查询)。
您是想说绑定 50 个变量效率低下,然后设置批量 50 个 sql 更新语句。我对您的回答的理解是否正确?【参考方案3】:
如果这只是出于好奇而提出的问题,我会说它更多地取决于数据库而不是准备好的语句。数据库操作比移动一些字节要昂贵得多。
如果你问这个问题是因为你想让你的应用程序更快,我不得不问这个更新是否真的是一个性能瓶颈。你量过吗?
如果这不是性能瓶颈,并且您想优化以防万一:不要。拥有可维护的代码比优化非关键代码更重要。使用复杂度最低且最容易理解的变体:变体 2。
【讨论】:
非常感谢您的回答方式。上面的代码是示例代码,但它代表了我的应用程序中的代码。现在我的首要任务是优化,可维护性是次要的..以上是关于IN子句效率中的preparedstatement设置值的主要内容,如果未能解决你的问题,请参考以下文章
PreparedStatement IN子句Regexp替代?
如何使用 WHERE x IN 子句为 PreparedStatement 编写 SQL?
PreparedStatement 可以不考虑 WHERE 子句中的某些条件吗?