sql—从数据库读取非常慢

kmb7vmvb  于 2021-07-26  发布在  Java
关注(0)|答案(1)|浏览(300)

我使用springboot和springdatajpa、hibernate和oracle。
实际上,我的表中有大约一千万条记录,我需要做一些操作,将信息写入一个文件,然后删除记录。
这是一个基本的sql查询

select * from zzz where  status = 2;

我做了一个测试,没有做操作,删除了记录

long start = System.nanoTime();
    int page = 0;
    Pageable pageable = PageRequest.of(page, LIMIT);

    Page<Billing> pageBilling = billingRepository.findAllByStatus(pageable);

    while (true) {
        for (Billing: pageBilling .getContent()) {
            //process
            //write to file
            //delete element
        }

        if (!pageBilling .hasNext()) {
            break;
        }

        pageable = pageBilling .nextPageable();
        pageBilling = billingRepository.findAllByStatus(pageable);

    }
    long end = System.nanoTime();
    long microseconds = (end - start) / 1000;
    System.out.println(microseconds + " to write");

结果很糟糕,限制在1万,用了157分钟,10万28分钟,百万19分钟。
有没有更好的解决方案来提高性能?

aor9mmx1

aor9mmx11#

以下可能会显著提高性能:
你不应该迭代过第一页。相反,删除已处理的数据并再次选择第一页。实际上,您不需要一个页面,就可以在方法名中对限制进行编码。选择较迟的页面效率很低。
加载、处理和删除一批项目的过程应在单独的事务中进行。否则 EntityManager 会容纳所有的实体,这会让事情变得非常缓慢。
如果这仍然不够,您可以研究以下内容:
检查执行的sql。看起来合理吗?如果没有,考虑切换到 JdbcTemplate 或者 NamedParameterJdbcTemplate 用一个 query 方法需要 RowCallbackHandler 您应该能够用一条select语句加载和处理所有行,并在最后处理一条delete语句以删除所有行。这要求用于筛选的状态在同一时间内不发生更改。
执行计划怎么样?如果他们看起来不合适,检查你的指数。

相关问题