作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
表中有超过 10,00,000 条记录,我正在处理。我需要为每条记录执行异步操作(推送队列)。一次获取所有记录并循环处理每条记录感觉像是一个坏主意。相反,我想分批获取记录并遍历每批。在互联网上的某处阅读有关使用 setFetchSize(int n) 进行批量查询的信息,我的 DAO 如下所示:
public List<UserPreferenceDTO> getUserPreferences() {
String sqlQueryString = "select us.id as userId, pf.id as preferenceId from users us, preferences pf where us.id = pf.user_id;";
SQLQuery sqlQuery = (SQLQuery) session.createSQLQuery(sqlQueryString).setFetchSize(200);
return sqlQuery.addScalar("userId").addScalar("preferenceId").setResultTransformer(new AliasToBeanResultTransformer(UserPreferenceDTO.class)).list();
}
我的服务类如下所示:
List<UserPreferenceDTO> userPreferenceDTOs = userDeviceDao.getUserPreferences();
for(UserPreferenceDTO userPreferenceDTO: userPreferenceDTOs ){
pushToRabbitMQ(userPreferenceDTO);
}
我需要从数据库中获取“N”条记录,将它们推送到队列中进行处理,然后再获取“N”条记录将它们推送到队列中,依此类推,直到所有记录都推送到队列中。
最佳答案
合理的 setFetchSize()
在任何批量加载场景中都是必须的,因为数据库不必单独发送每一行。即使您与数据库的往返只是 10ms
,它仍然需要 10ms * 10mln ~ 28 h
来完成所有行。改进通常稳定在 1000 左右,但这取决于您的环境设置,因此您需要对其进行测试。
将 .list()
替换为 .scroll()
可能就足够了,它返回 ScrollableResults
允许一次读取一条记录时间。然而,这将取决于数据库,有些像 MySQL will fake the scrolling and load the entire result set .
如果是这种情况,您需要在包含 setFirstResult()
和 setMaxResult()
的查询中使用 ORDER BY
。这将执行新查询以读取每个批处理。这是最安全的方法,但 ORDER BY
可能是一种昂贵的语句。
关于java - 如何批量选择所有表记录,并逐批处理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49676777/
我是一名优秀的程序员,十分优秀!