高阶低通滤波算法
介绍
在我以前的文章中,我谈到了各种数据库标识符策略,在设计数据库模型时需要注意。 我们得出的结论是,数据库序列非常方便,因为它们在大多数用例中既灵活又高效。
但是,即使具有缓存的序列 ,应用程序也需要为每个新的序列值进行数据库往返。 如果您的应用程序要求每个事务执行大量插入操作,则可以使用hi / lo算法优化序列分配。
高/低算法
高/低算法将序列域分为“高”组。 同步分配一个“ hi”值。 每个“ hi”组都有最大数量的“ lo”条目,可以通过离线分配它们,而不必担心并发重复的条目。
- “ hi”令牌是由数据库分配的,并且保证两个并发调用可以看到唯一的连续值
- 一旦检索到“ hi”令牌,我们只需要“ incrementSize”(“ lo”条目的数量)
- 标识符范围由以下公式给出:
-
而“ lo”值将取自:
从...开始:
- 使用所有“ lo”值时,将获取新的“ hi”值,并且循环继续
在这里,您可以有两个并发事务的示例,每个事务都插入多个实体:
测试理论
如果我们具有以下实体:
@Entity
public class Hilo {
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "hilo_sequence_generator")
@GenericGenerator(
name = "hilo_sequence_generator",
strategy = "org.hibernate.id.enhanced.SequenceStyleGenerator",
parameters = {
@Parameter(name = "sequence_name", value = "hilo_seqeunce"),
@Parameter(name = "initial_value", value = "1"),
@Parameter(name = "increment_size", value = "3"),
@Parameter(name = "optimizer", value = "hilo")
})
@Id
private Long id;
}
我们可以检查在插入多个实体时发出了多少次数据库序列往返:
@Test
public void testHiloIdentifierGenerator() {
doInTransaction(new TransactionCallable<Void>() {
@Override
public Void execute(Session session) {
for(int i = 0; i < 8; i++) {
Hilo hilo = new Hilo();
session.persist(hilo);
session.flush();
}
return null;
}
});
}
哪些最终生成以下SQL查询:
Query:{[call next value for hilo_seqeunce][]}
Query:{[insert into Hilo (id) values (?)][1]}
Query:{[insert into Hilo (id) values (?)][2]}
Query:{[insert into Hilo (id) values (?)][3]}
Query:{[call next value for hilo_seqeunce][]}
Query:{[insert into Hilo (id) values (?)][4]}
Query:{[insert into Hilo (id) values (?)][5]}
Query:{[insert into Hilo (id) values (?)][6]}
Query:{[call next value for hilo_seqeunce][]}
Query:{[insert into Hilo (id) values (?)][7]}
Query:{[insert into Hilo (id) values (?)][8]}
如您所见,对于8个插入的实体,我们只有3个序列调用。 实体插入的事务越多,我们需要的越少,从减少数据库序列往返次数中获得的性能就会越好。
翻译自: https://www.javacodegeeks.com/2014/06/the-hilo-algorithm.html
高阶低通滤波算法