OneToMany /可为空关系的休眠性能问题

Posted

技术标签:

【中文标题】OneToMany /可为空关系的休眠性能问题【英文标题】:Hibernate performance issue with OneToMany / nullable relationship 【发布时间】:2010-02-05 22:51:58 【问题描述】:

我们使用@OneToMany 表示我们的 Parent->Child->Child->Child DB 关系:

@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name = "THE_ID", nullable = false )
private List<ChildClass> children = new ArrayList<ChildClass>();

我们有一个场景,其中包含大量数据(100K 插入),插入时性能非常糟糕(实际上超时)。但是,对于少量数据(1K 插入),我们就可以了。

所以我无缘无故地删除了nullable = false 并更改了子表上的数据库外键以允许空值,并且性能非常好。谁能解释一下?


更新:打开调试.. 使用nullable = false 似乎存在为子表生成 id 的巨大瓶颈。我们超时等待 id 生成,并在日志中一遍又一遍:

[org.hibernate.event.def.AbstractSaveEventListener] [ ] generated identifier: <743088>, using strategy: org.hibernate.id.IncrementGenerator

我们甚至从未将数据插入数据库。我们只是停留在 id gen 上。目前我们配置 Hibernate 通过查看当前子表中的最大 id 值来生成 ID:

@Id
@GeneratedValue(generator = "DummyString")
@GenericGenerator(name = "DummyString", strategy = "increment")
@Column(name = "THE_ID", nullable = false)
private Long id;

在此之前,我们使用 DB 序列并遇到了同样的问题。

当我们省略 nullable = false 时,我们确实看到了这些 ID 生成语句(其中 108K),但它们在 25 秒内完成。那么为什么这些声明(字面意思)与nullable = false 一起永远存在?

【问题讨论】:

【参考方案1】:

巫毒? 了解如何执行 Oracle 跟踪。您的 DBA 应该会有所帮助。

使用跟踪文件,您可以查看 Oracle 的等待事件。这将告诉您当“性能非常糟糕”时数据库在做什么。它可能正在等待一个锁,它可能正在读取一个表......

一旦你知道它为什么慢,解决方案通常就会变得显而易见。

我向开发人员推荐此whitepaper,作为使用数据库的指导。

【讨论】:

以上是关于OneToMany /可为空关系的休眠性能问题的主要内容,如果未能解决你的问题,请参考以下文章

具有 OneToMany 关系的休眠重复条目

没有主键和可为空字段的休眠实体

OneToMany 关系中的休眠标准

无法在休眠中删除 OneToMany 关系的实例

非主键之间的休眠关系OneToMany

无法使用 OneToMany 和 ManyToOne 关系在休眠中创建表(也无法创建外键)