- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我有一个名为 OrderEvent 的父实体和一个名为 PreCondition 的子实体。一个 OrderEvent 可以有多个 PreConditions(>= 200)。我需要保存 100000 OrderEvent + 100000 * 200 PreCondition。我使用 Repository.save(list Of OrderEvents) 并为每 1000 条记录保存到数据库中。插入 1000 个 OrderEvents 大约需要 30 秒。
保存所有 100000 个 OrderEvents 需要将近一个小时。
有什么方法可以将时间缩短到 2 分钟以下?
尝试保存存储库的实体方法
public void parseOrder(String path, String collectionName) throws ParseException {
BufferedReader reader;
Connection conn = (Connection) em.unwrap(java.sql.Connection.class);
System.out.println(conn);
try {
reader = new BufferedReader(new FileReader(
path));
String line = reader.readLine();
String jobNumber = line.substring(0, 7).trim();
String recordType = line.substring(7, 9).trim();
Integer len = line.length();
preId = 0L;
postId = 0L;
eventId = 0L;
OrderEvent orderEvent = this.paraseHeader(line,len,jobNumber,collectionName);
Integer count = 1;
Integer batch = 0;
long startTime = System.nanoTime();
List<OrderEvent> list = new ArrayList<OrderEvent>();
while (line != null) {
line = reader.readLine();
if (line == null) {
continue;
}
jobNumber = line.substring(0, 7).trim();
recordType = line.substring(7, 9).trim();
len = line.length();
if (recordType.equals("0H")) {
count++;
batch++;
if (batch.equals(1000)) {
orderRepository.save(list);
list.clear();
long estimatedTime = System.nanoTime() - startTime;
System.out.println("Processed " + batch + " records in " + estimatedTime / 1_000_000_000. + " second(s).");
batch = 0;
startTime = System.nanoTime();
}
list.add(orderEvent);
//orderRepository.saveAndFlush(orderEvent);
orderEvent = this.paraseHeader(line,len,jobNumber,collectionName);
} else if (recordType.equals("2F")) {
this.paraseFeature(line,len,jobNumber,orderEvent);
}
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private OrderEvent paraseHeader (String line,Integer len,String jobNumber,String collectionName) throws ParseException {
String model = line.substring(9, 16).trim();
String processDate = line.substring(len-11,len-3).trim();
String formattedProcessDate = processDate.substring(0,4) + "-" +
processDate.substring(4,6) +"-" + processDate.substring(6,8) + " 00:00:00";
//eventId++;
OrderEvent orderEvent = new OrderEvent(jobNumber,UUID.randomUUID().toString(),collectionName,
formatter.parse(formattedProcessDate));
// preId++;
//postId++;
orderEvent.fillPrecondition("Model", "Stimulus", "OP_EQ", model);
orderEvent.fillPostcondition("Add_Fact","Coded","Response","True");
return orderEvent;
}
private void paraseFeature (String line,Integer len, String jobNumber, OrderEvent orderEvent) {
// preId++;
String feature = line.substring(len-7,len).trim();
orderEvent.fillPrecondition("Feature", "Stimulus", "OP_EQ", feature);
}
最佳答案
这通常取决于数据库设置,例如客户端的延迟是多少,表上的索引是什么,查询如何锁定表等等。
确保您了解在网络操作上花费了多少时间。这可能是限制因素,尤其是当您的数据库位于世界的另一端时。
首先确定客户端和数据库服务器之间的延迟是多少。如果它是 10 毫秒,那么逐行插入将是:100,000 * 200 * 10ms = 200000s ~ 56h。这非常慢,因此请确保您使用的是 JDBC 批量插入。
有时可以通过创建影子表显着加快插入过程:
OrderEvents
和 PreCondition
表相同的新表。一些 RDBMS 允许使用 CREATE TABLE ... AS SELECT ... FROM ...
语法。INSERT INTO ... SELECT ... FROM ...
。然而,最好的选择是跳过 JDBC 并切换到数据库提供的批量加载实用程序,例如Oracle 数据库有 External Tables和 SQL*Loader .这些工具专为高效摄取大量数据而设计,而 JDBC 是一个通用接口(interface)。
关于java - 如何超快地插入 100,000 个父行,每个父行有 200 个子行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55418967/
我是一名优秀的程序员,十分优秀!