开发者社区> 问答> 正文

大数据量进行关联查询后更新至主表如何优化

场景:主表为客户表,每天都需要从另外5张中间表里匹配到对应客户的信息,将其更新到客户表

使用的数据库为oracle,目前使用的做法是“update set select from left join ....”的方式

特殊情况:客户表里,客户编号是主键,但是在其他5张表里客户编号不是,所以在进行关联查询时,每张表都以客户编号,做了开窗操作,做到随机取一条

目前优化:将另外的5张表里,和主表匹配不到的数据将其全部删除,然后再开始跑更新逻辑;且做关联的字段都已加了索引

想咨询下各位大佬,在sql层面,有更好的优化方案吗?或者如果要修改为java代码的方式,在代码层面上有其他优化的方案吗?

展开
收起
LinTa0 2023-08-19 21:35:12 57 0
2 条回答
写回答
取消 提交回答
  • 在Oracle中,UPDATE SET子句通常用于在一个查询中更新多个列。然而,这种方法并不高效,因为它会导致多次扫描和处理每个结果集。此外,UPDATE SET子句还受到SQL规范中的限制,即不能直接使用JOIN语句。

    一种替代方法是在Java代码中执行这些操作。这样可以避免多次扫描和处理每个结果集的问题,并且可以更好地控制事务和提交过程。

    以下是一个示例,展示了如何在Java代码中执行类似的操作:

    import java.util.List;
    import org.springframework.jdbc.core.JdbcTemplate;
    import org.springframework.stereotype.Repository;
    @Repository
    public class CustomerDao {
        private JdbcTemplate jdbcTemplate;
        // 构造函数注入
        public void updateCustomerInfo() {
            String sql = "SELECT * FROM customer"; // 假设customer表中有id、name等属性
            List<Map<String, Object>> customers = this.jdbcTemplate.queryForList(sql);
            for (Map<String, Object> customer : customers) {
                Long id = Long.parseLong(customer.get("id").toString());
                String name = customer.get("name").toString();
                // 从中间表获取信息
                String intermediateTableSql = "SELECT * FROM INTERMEDIATE_TABLE WHERE CUSTOMER_ID = ?";
                List<Map<String, Object>> infoFromIntermediateTables = this.jdbcTemplate.queryForList(intermediateTableSql, new Object[]{id});
                if (infoFromIntermediateTables == null || infoFromIntermediateTables.isEmpty()) {
                    // 如果找不到信息,则删除该客户记录
                    this.jdbcTemplate.update("DELETE FROM CUSTOMER WHERE ID = ?", new Object[]{id});
                } else {
                    // 如果找到了信息,则更新客户记录
                    this.jdbcTemplate.update("UPDATE CUSTOMER SET NAME = ? WHERE ID = ?", new Object[]{name, id});
                }
            }
        }
    }
    

    在这个例子中,我们首先通过一个简单的SQL查询从customer表中获取所有客户记录。然后,我们遍历这些记录,从中间表中获取与之匹配的信息。如果找到信息,我们就更新customer表中的客户记录。如果找不到信息,我们就删除该客户记录。

    这种方法的好处在于我们可以更好地控制事务和提交过程,而且可以在一次查询中更新多个列。

    2023-08-20 09:23:49
    赞同 1 展开评论 打赏
  • 在 SQL 层面,有一些优化可以考虑:

    1、批量操作而非逐行处理:在处理大量数据时,逐行处理通常效率较低。如果可能,尝试批量操作,例如使用 IN 语句或 MULTI-TABLE UPDATE。

    2、优化数据类型和索引:确保所有相关的列都使用了最优的数据类型,这可以减少存储和计算的需求。对经常用于查询的列添加索引,可以大大提高查询速度。

    3、使用视图代替临时表:如果可能,尝试使用视图代替临时表。视图在创建后只计算一次,而临时表可能会在每次查询时重新计算。

    4、使用连接而不是子查询:在某些情况下,连接查询可能比子查询更快。

    5、尽可能减少数据库交互:尽量在一次数据库交互中完成所有需要的操作,而不是多次交互。

    在 Java 代码层面,可以考虑以下优化:

    1、使用批处理:如果你在 Java 中使用 JDBC 更新大量数据,使用批处理可以大大提高性能。

    2、减少数据库交互:和 SQL 层面的优化一样,尽量在一次数据库交互中完成所有需要的操作。

    3、预加载和缓存:预加载可能需要的对象或数据,然后在需要时从缓存中获取,而不是每次需要时都从数据库中获取。

    4、使用连接池:连接池可以重用已经创建的数据库连接,避免了每次操作都要创建和关闭连接的开销。

    在实施任何优化措施之前,都应先进行性能测试,以确保优化措施的效果。

    2023-08-20 09:02:30
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
大数据AI一体化的解读 立即下载
极氪大数据 Serverless 应用实践 立即下载
大数据&AI实战派 第2期 立即下载