2013-03-11 93 views
4

我在尝试将Hibernate与不支持AUTO_INCREMENT(http://scn.sap.com/thread/3238906)的SAP HANA内存数据库连接时遇到了一些性能问题。优化休眠序列ID生成

所以我设置了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后,才开始实际插入。

总而言之,向内存数据库插入40000条记录(通过网络到远程数据库)需要大约5分钟的时间,这对于内存数据库来说非常缓慢。我认为它是因为Hibernate的一个选择的ID一个未来值:

send a request to database 
get id 
send next request 
... 

我想加快ID生成,但不幸的是,我没有足够的理解它是如何工作来提高它。我已经搜索了可能的解决方案,并发现了以下想法:

1)调用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), 

我得到“无法从SequenceHiLoGenerator转换为注释”错误在Eclipse

3)写插入数据库触发器。然而,对我来说,它看起来像一个糟糕的解决方案,因为我想要一个通用的Hibernate Dialect与任何数据库实例一起工作。我不知道如何在Hibernate方言中包含这样的触发器。

你会建议哪种解决方案?你还有其他建议吗?

我会真诚地感谢这个问题的任何帮助。如果有人能够提供一些解决方案或文档或者甚至更详细的解决方案,那将是非常好的。

非常感谢您提前。

回答

2

来自序列的值被逐一取出,因为allocationSize设置为1. allocationSize的默认值为50,这已经好很多了。在这种特殊情况下,如果插入40000记录是典型用例,那么使用高于该值的值可能是有意义的。

如果创建序列的脚本是自写的(而不是Hibernate),则INCREMENT BY的值应该与allocationSize的值相同。

+0

我不确定这是否正确。看[这个问题](http://stackoverflow.com/questions/12745751/hibernate-sequencegenerator-and-allocationsize)。 – 2013-03-12 09:50:26

+1

如果您不确定,请尝试。当一个一个分配问题时,一次分配更多可能会有所帮助。 – 2013-03-12 18:35:19

+0

我试过'allocationSize = 1000',并且性能得到了改善。序列产生得足够快。但是,数据库仍然非常慢 - 本地数据库每秒大约500次插入 - 这对于内存数据库非常不利。但它应该是另一个问题/问题。 – 2013-03-18 11:08:03