尝试将Hibernate与SAP HANA内存数据库连接时遇到一些性能问题,该数据库不支持AUTO_INCREMENT(http://scn.sap.com/thread/3238906)。
因此,我将Hibernate设置为使用序列进行ID生成。
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="myseq") @SequenceGenerator(name="myseq",sequenceName="MY_SEQ",allocationSize=1)
但是,当我插入大量记录(例如40000)时,Hibernate首先会生成ID。看起来像:
DEBUG Thread-1 org.hibernate.SQL - select MY_SEQ.nextval from DUMMY DEBUG Thread-1 org.hibernate.id.SequenceGenerator - Sequence identifier generated: BasicHolder[java.lang.Long[92080]] DEBUG Thread-1 org.hibernate.event.internal.AbstractSaveEventListener - Generated identifier: 92080, using strategy: org.hibernate.id.SequenceHiLoGenerator DEBUG Thread-1 org.hibernate.SQL - select MY_SEQ.nextval from DUMMY DEBUG Thread-1 org.hibernate.id.SequenceGenerator - Sequence identifier generated: BasicHolder[java.lang.Long[92081]] DEBUG Thread-1 org.hibernate.event.internal.AbstractSaveEventListener - Generated identifier: 92081, using strategy: org.hibernate.id.SequenceHiLoGenerator
并且只有在生成所有ID之后,它才开始实际插入。
总之,大约需要5分钟才能插入40000条记录(通过网络到远程数据库),这对于内存数据库来说非常慢。我认为发生这种情况是因为Hibernate一对一地选择了ID的下一个值:
send a request to database get id send next request ...
我想加快ID生成的速度,但是不幸的是,我对ID如何改进它还不够了解。我搜索了可能的解决方案,并发现以下想法:
1) 在insert语句中调用sequence.nextval 。但是,Hibernate小组说这是不可能的:https : //forum.hibernate.org/viewtopic.php?f=1&t=932506
2) 使用SequenceHiLoGenerator 。这可能是一个解决方案,但我不知道如何设置…如果我写
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="myseq") @SequenceHiLoGenerator(name="myseq",sequenceName="MY_SEQ",allocationSize=1),
我在Eclipse中收到“无法从SequenceHiLoGenerator转换为注释”错误
3) 在inserts上编写一个数据库触发器 。但是,对我来说,这似乎是一个糟糕的解决方案,因为我想让通用的Hibernate Dialect与任何数据库实例一起使用。而且我不了解如何在Hibernate方言中包含这样的触发器。
您会建议哪种解决方案? 你还有其他建议吗?
在此问题上的任何帮助,我将由衷的感谢。如果有人可以提供一些解决方案或文档,或者甚至只是提供解决方案的更详细途径,那将是很好的。
提前非常感谢您。
序列中的值被一一读取,因为allocationSize设置为1。默认值为allocationSize50,这已经更好了。在这种特殊情况下,如果插入40000条记录是典型的用例,则使用高于该值的值可能是有意义的。
allocationSize
如果用于创建序列的脚本是自行编写的(而不是由Hibernate编写),则的值INCREMENT BY应与的值相同allocationSize。
INCREMENT BY