1)
я предлагаю использовать алгоритм HILO для генерации всех идентификаторов. Используйте разные последовательности для каждой таблицы. С размером распределения использования HILO alg около 1000. Это означает, что select nextval будет выполняться один раз для каждого 1000 записей.
2)
Использование JDBC пакетной вставки с размером, который является кратным размеру выделения хило. К примеру 2000, 3000 и т.д.
3)
Проверьте, если ваша БД может обрабатывать так много записей в одной транзакции. Если нет, вы, вероятно, должны зафиксировать tx после каждой вставки пакета.
-
Я использовал этот шаблон для переноса 300 млн записей на лету обработки Java из одной системы в другую. В некоторых таблицах скорость вставки была выше 5000 записей в секунду.
Ad 1) - реализация HILO
public interface IdentifierGenerator {
int getNextId();
}
HiloGenerator:
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());
}
}
Лучший время для оптимизации никогда. Второе - лучшее время, когда у вас есть реальная проблема с производительностью. Время WORST во время разработки. Напишите самый простой и простой код, который вы, возможно, сможете. Не пытайтесь угадать, где будут узкие места в производительности - программное обеспечение тратит огромное количество времени в самых прочных местах! НЕ тратите огромное количество времени на ускорение своей Java - в конце концов, это вряд ли изменит ситуацию. Независимо от того, какой причудливый код Java-кода вы придумали, время INSERT базы данных будет доминировать во время выполнения. Поделитесь и наслаждайтесь. –