java - 更新单个表的多行

标签 java mysql

我需要更新超过 60k 行的表格的每一行。 目前我是这样做的:

public void updateRank(Map<Integer, Double> map) {
    Iterator<Map.Entry<Integer, Double>> it = map.entrySet().iterator();
    while (it.hasNext()) {
        Map.Entry<Integer, Double> pairs = (Map.Entry<Integer, Double>) it.next();
        String query = "update profile set rank = " + pairs.getValue()
                + " where profileId = " + pairs.getKey();
        DBUtil.update(query);
        it.remove();
    }
}

仅此方法就需要大约 20 多分钟才能完成,我认为这里的每一行 (60k) 都会访问数据库。(尽管我使用 dbcp 进行连接池,最大 Activity 连接数为 50)

如果我能够通过单个数据库命中来更新行,那就太好了。那可能吗 ?怎么样?

或任何其他方法来改善这里的时间安排?

最佳答案

如果每一行都应该得到一个不同的值,而该值不能从数据库中的现有数据中派生出来,那么您就无法优化整体复杂性。所以不要期待太多奇迹。

也就是说,您应该开始使用准备好的语句和批处理:

public void updateRank(Map<Integer,Double> map){
    Iterator<Entry<Integer, Double>> it = map.entrySet().iterator();
    String query = "";
    int i = 0;

    Connection connection = getConnection(); // get the DB connection from somewhere
    PreparedStatement stmt = connection.prepareStatement("update profile set rank = ? where profileId = ?");

    while (it.hasNext()) {
        Map.Entry<Integer,Double> pairs = (Map.Entry<Integer,Double>)it.next();
        stmt.setInt(1, pairs.getValue());
        stmt.setDouble(2, pairs.getKey());
        stmt.addBatch(); // this will just collect the data values
        it.remove();
    }       
    stmt.executeBatch(); // this will actually execute the updates all in one
}

这是做什么的:

  1. 预处理语句使SQL解析器只解析一次SQL
  2. 批处理最大限度地减少了客户端-服务器往返次数,因此不会每次更新都进行一次
  3. 客户端和服务器之间的通信被最小化,因为 SQL 只传输一次并且数据被收集并作为数据包(或至少更少的数据包)发送

此外:

  • 请检查数据库列 profileId 是否正在使用索引,以便能够足够快地查找相应的行
  • 您可以检查您的连接是否设置为自动提交。如果是这样,请尝试禁用自动提交并在更新所有行后显式提交事务。这样,单个更新操作也可以更快。

关于java - 更新单个表的多行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20354684/

相关文章:

java - 什么java语句或函数来格式化尼日利亚奈拉货币的货币

php - MySQL Numrows 期望参数

mysql - VB.Net Query For MYSQL 查询在集合中查找

java - 无法使用 spring cli 命令启动groovy应用程序

java - 如何在 Windows 10 上使用 Java 判断 wifi 或蜂窝连接

java - 哈希表、ConcurrentHashMap 和数据可见性

java - 服务器重启后如何将 HazelcastClient 重新连接到 HazelcastServer

php - 将数据插入数据库是不好的做法吗?

java - Hql 子句在子句 case 中为空,不像在 mysql 中那样工作

mysql - SQL 最后插入到 Drupal 中。它真的是线程安全的吗?