我正在考虑在表中更新多行看似简单的任务的三种替代方法。我想知道哪一个在效率和代码可读性方面最好。虽然我不确定效率问题是否有明确的答案,这可能取决于所使用的数据库。
在我的特定情况下,我使用PostgresSQL作为数据库,并且该表包含不到一百万个条目。我现在有一个进程负责从该表中提取数据子集,执行一些工作,然后使用时间戳更新这些行。
我认为有三种选择:
使用in子句构造单个update语句,其内容将替换为包含要更新的行ID的构造字符串。
String update = "update mytable set mydate = now() where id in (?)";
StringBuilder ids = new StringBuilder();
for (Item item : items) {
ids.append(item.getId()).append(",");
}
ids.setLength(ids.length() - 1);
update.replace("?", ids.toString());
ps = con.prepareStatement(update);
ps.executeUpdate();
使用批次
ps = con.prepareStatement("update mytable set mydate = now() where id = ?");
for (Item item : items) {
ps.setInt(1, item.getId());
ps.addBatch();
}
ps.executeBatch();
使用交易
con.setAutoCommit(false);
ps = con.prepareStatement("update mytable set mydate = now() where id = ?");
for(Item item : items) {
ps.setInt(1, item.getId());
ps.executeUpdate();
}
con.commit();
哪一项被认为是最佳做法?或者你会提出另一种方式吗?我个人喜欢第二个选项,它简洁易用,但我的直觉是第一选项将是最高性能。
答案 0 :(得分:1)
对您的建议的想法
该事务具有允许回滚更新的明显优势。
构造的SQL语句存在破坏的风险,同时请注意,您正在通过网络发送批次数据。
其他建议
加入临时表 我将创建一个临时表,其中包含要更新的所有值,然后构造一个update-statement,其中包含要更新的临时表的连接。
使用副本
如果是原始速度,那么我建议copy
语句后,请参阅:
http://wiki.postgresql.org/wiki/COPY