【发布时间】:2019-03-30 14:33:49
【问题描述】:
我正在尝试找到在 Spring/Hibernate 服务中从 MySQL 数据库加载大量数据的最佳/最佳方式。
我从第 3 方 API 中提取大约 10 万条记录(通常在 300-1000 之间的块中),然后我需要从数据库中提取每条记录的翻译,因为有 30 种语言,这意味着每条记录将有 30 行,所以 1000来自 API 的记录是来自数据库的 30,000 行。
来自 API 的记录以 POJO 的形式(超小尺寸)说我得到 1000 条记录,我将列表分成多个 100 条记录列表,然后收集每条记录的 id 并从数据库中为这条记录选择所有翻译。我只需要表中的两个值,然后将它们添加到我的 POJO 中,然后将 POJO 推送到下一个服务。
基本上是这样的:
interface i18nRepository extends CrudRepository<Translation, Long> {}
List<APIRecord> records = api.findRecords(...);
List<List<APIRecord>> partitioned = Lists.partition(records, 100); // Guava
for(List<APIRecord> chunk : partitioned) {
List<Long> ids = new ArrayList();
for(APIRecord record : chunk) {
ids.add(record.getId());
}
List<Translation> translations = i18Repository.findAllByRecordIdIn(ids);
for(APIRecord record : chunk) {
for(Translation translation : translations) {
if (translation.getRedordId() == record.getId()) {
record.addTranslation(translation);
}
}
}
}
就 spring-boot/hibernate 属性而言,我只设置了默认属性。我想让它尽可能高效、快速和内存精简。我的一个想法是使用底层 API 而不是 Hibernate 来绕过对象映射。
【问题讨论】:
-
您可以使用
PagingAndSortingRepository界面对结果进行分页 -
可以缓存数据库中的数据。试试
ehcache,您可以快速添加它进行测试。重要的是您希望结果的实时性。 -
文档中有几条建议:docs.jboss.org/hibernate/orm/current/userguide/html_single/…。我要补充一点,您的嵌套循环算法是 O(n^2)。使用 Map 会将其变成 O(n) 算法。但无论如何:你的问题是什么?
-
1.你应该使用
join。 2. 选择PageRequest的记录分块加载数据。 3.如果你的结果那么大。您可以使用临时表来保存结果。 -
@S.Denis
join?什么 ? PageRequest 似乎是个好主意。
标签: java mysql spring hibernate spring-data-jpa