gpt4 book ai didi

java - 以最小的开销插入两个表

转载 作者:行者123 更新时间:2023-12-02 05:27:38 24 4
gpt4 key购买 nike

我有一个新应用程序将插入大量数据,并且必须能够每秒处理多次插入。数据库模式由两个表组成:HEADER 和 DETAIL 表。 HEADER 表包含一些最少的信息,DETAIL 表包含不会更新的大量数据。

HEADER 记录对 ID 字段有 PK 约束。 ID 值由序列生成器在插入时创建。 DETAIL.HEADER_ID 字段对 HEADER.ID 字段具有 FK 约束。

我的问题是哪个选项执行最快的插入?这将在 Weblogic 11g、Oracle 11g 上运行。每秒插入次数超过 1000 次。

1)在HEADER插入上使用JDBC的Statement.RETURN_GENERATED_KEYS选项,获取生成的键,然后插入DETAIL记录。

2)首先调用sequence.nextval,然后插入HEADER记录,然后插入DETAIL记录。

3) 以某种方式获取序列 ID block ,插入所有 HEADER 记录,然后插入所有 DETAIL 记录。 (如何获取序列 ID block ?)。

最佳答案

1)

我建议使用HILO算法来生成所有ID。每个表使用不同的顺序。对于 HILO alg,使用的分配大小约为 1000。这意味着 select nextval 将每 1000 条记录执行一次。

2)

使用 jdbc 批量插入,其大小为 HILO 分配大小的倍数。例如2000、3000等。

3)

检查您的数据库是否可以在一个事务中处理这么多记录。如果不是,您可能应该在每次批量插入后提交 tx。

--

我使用这些模式通过即时 Java 处理将 3 亿条记录从一个系统迁移到另一个系统。在某些表中插入速度超过5000条记录/秒。

广告 1) - 实现 HILO

public interface IdentifierGenerator {

int getNextId();
}

希洛发电机:

public class HiLoSequenceGenerator implements IdentifierGenerator {

private String sequenceName;
private int allocationSize;

private IdentifierDao dao;

private boolean initialized;
private int min;
private int max;
private int next;

public HiLoSequenceGenerator() {
}

public HiLoSequenceGenerator(String sequenceName, int allocationSize, IdentifierDao dao) {
this.sequenceName = sequenceName;
this.allocationSize = allocationSize;
this.dao = dao;
}

@Override
public int getNextId() {
return next();
}

private synchronized int next() {

if (!initialized) {
alloc();
initialized = true;
}

if (next > max) {
alloc();
}

return next++;
}

private void alloc() {

// fetch unique number from sequence
int unique = dao.getUniqueId(sequenceName);

// prepare buffer (pool of identifiers)
min = unique * allocationSize;
max = min + allocationSize - 1;
next = min;

if (log.isTraceEnabled()) {
log.trace("allocated id buffer based on " + sequenceName + ": [" + min + " - " + max + "]");
}
}

在这里您可以看到 HILO 如何使用分配大小 3 和 mockito 单元测试:

public class HiLoSequenceGeneratorTest {

@Test
public void test() {

// given
IdentifierDao dao = mock(IdentifierDao.class);
when(dao.getUniqueId(anyString())).thenReturn(3, 4, 10, 11);

HiLoSequenceGenerator gen = new HiLoSequenceGenerator("seq", 3, dao);

// 3: 9, 10, 11
// 4: 12, 13, 14
//10: 30, 31, 32
//11: 33, 34, 35

// when - then
assertEquals(9, gen.getNextId()); // hit db
assertEquals(10, gen.getNextId());
assertEquals(11, gen.getNextId());
assertEquals(12, gen.getNextId()); // hit db
assertEquals(13, gen.getNextId());
assertEquals(14, gen.getNextId());
assertEquals(30, gen.getNextId()); // hit db
assertEquals(31, gen.getNextId());
assertEquals(32, gen.getNextId());
assertEquals(33, gen.getNextId()); // hit db
assertEquals(34, gen.getNextId());
assertEquals(35, gen.getNextId());
}

}

关于java - 以最小的开销插入两个表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25857568/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com