Spring Data Jpa 更新表中的20M条记录,并使用spring Boot 为每条记录设置col1 = col2 + col3

o4tp2gmn  于 4个月前  发布在  Spring
关注(0)|答案(2)|浏览(87)

更新表中的20M条记录,并使用spring Boot 为每条记录设置col1 = col2 + col3。

try (Connection connection = dataSource.getConnection()) {
            String updateQuery = "UPDATE table SET col1 = ? WHERE id = ?";
            PreparedStatement preparedStatement = connection.prepareStatement(updateQuery);

        for (TableEntity entity : tableEntities) {
            preparedStatement.setInt(1, calculate(offersLeadScore)); // Set new col1
            preparedStatement.setObject(2, entity.getId());
            preparedStatement.addBatch();
        }
        preparedStatement.executeBatch();`

字符串
上面的方法花费了很多时间来执行和更新表中的所有记录。
如何使用Sping Boot 实现更快的执行?
已尝试JPA的saveAll()及以上方法。无法优化它。
需要一些行业标准的方法来更新一个表中的所有记录更快的方式。

cpjpxq1n

cpjpxq1n1#

尝试这种方法,它通过使用名为TableService的Sping Boot 服务来有效地更新数据库表中2000万条记录的大数据集。updateCol 1ForTable函数包含主要操作。此方法构建SQL更新查询,使用记录的id作为引用,将col 1的新值计算为每条记录的col 2和col 3之和。下面是代码;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.List;

@Service
public class TableService {

    private final JdbcTemplate jdbcTemplate;

    @Autowired
    public TableService(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    public void updateCol1ForTable(List<TableEntity> tableEntities) {
        String updateQuery = "UPDATE your_table_name SET col1 = col2 + col3 WHERE id = ?";
        
        jdbcTemplate.batchUpdate(updateQuery, new BatchPreparedStatementSetter() {
            @Override
            public void setValues(PreparedStatement preparedStatement, int i) throws SQLException {
                preparedStatement.setLong(1, tableEntities.get(i).getId());
            }

            @Override
            public int getBatchSize() {
                return tableEntities.size();
            }
        });
    }
}

字符串
要有效地批量更新记录,请从服务层或控制器调用此函数。
希望能成功:)

6qqygrtg

6qqygrtg2#

为什么?为什么?您最多只是引入了一个维护难题。或col 3被更新,并且每次插入一行。一个更好的解决方案是在select上执行计算。这是对select的一次维护。如果出于某种原因,您认为需要存储派生结果,那么定义col1作为生成的。首先删除列,然后重新添加它:(demo here)

alter table <your_table_name> drop col1; 
alter table <your_table_name> 
      add col1 bigint
          generated always as (col2::bigint + col3::bigint) stored;

字符串
初始运行/设置不会很快。但代价是您无需进行维护,并且当添加行时以及每当col2' and/or col 3 '更新时,col1的值会自动计算。最初或之后不需要额外的维护。

相关问题