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