多个SQL更新最佳实践

时间:2011-08-29 14:40:31

标签: sql postgresql transactions

我正在考虑在表中更新多行看似简单的任务的三种替代方法。我想知道哪一个在效率和代码可读性方面最好。虽然我不确定效率问题是否有明确的答案,这可能取决于所使用的数据库。

在我的特定情况下,我使用PostgresSQL作为数据库,并且该表包含不到一百万个条目。我现在有一个进程负责从该表中提取数据子集,执行一些工作,然后使用时间戳更新这些行。

我认为有三种选择:

  1. 使用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();
    
  2. 使用批次

    ps = con.prepareStatement("update mytable set mydate = now() where id = ?");
    
    for (Item item : items) { 
        ps.setInt(1, item.getId());
        ps.addBatch();
    }
    
    ps.executeBatch();
    
  3. 使用交易

    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();
    
  4. 哪一项被认为是最佳做法?或者你会提出另一种方式吗?我个人喜欢第二个选项,它简洁易用,但我的直觉是第一选项将是最高性能。

1 个答案:

答案 0 :(得分:1)

对您的建议的想法
该事务具有允许回滚更新的明显优势。

构造的SQL语句存在破坏的风险,同时请注意,您正在通过网络发送批次数据。

其他建议

加入临时表 我将创建一个临时表,其中包含要更新的所有值,然后构造一个update-statement,其中包含要更新的临时表的连接。

使用副本
如果是原始速度,那么我建议copy语句后,请参阅:
http://wiki.postgresql.org/wiki/COPY