【问题标题】:How to overcome the performance issues caused by the generated SQL of union-subclass in Hibernate如何克服Hibernate中union-subclass生成SQL导致的性能问题
【发布时间】:2012-05-13 14:08:43
【问题描述】:

我正在使用 Hibernate 对 TABLE_PER_CLASS 继承策略的支持。功能方面它运作良好。每当发出多态查询时,Hibernate 都会为我的两个具体类 A 和 B 生成一个包含“union all”的 SQL。生成的 SQL 具有以下格式:

select C1, C2, C3 from (
    select C1, C2, C3 from ClassA
  union all
    select C1, C2, C3 from ClassB
)
where 
    C1 == <value>
order by C2
limit 100

这种方法的问题在于数据库端的性能非常差。考虑到 C1 列是 ClassA 和 ClassB 的共享属性(派生自抽象父级),Hibernate 可以在两个子选择中插入 where 子句并显着提高性能。例如,

select C1, C2, C3 from ( 
    select C1, C2, C3 from ClassA where C1 == <value>
    union all
    select C1, C2, C3 from ClassB where C1 == <value>
)
order by C2
limit 100

也可以对极限进行一些优化。 我在我的 DAO 层中使用 Hibernate 标准 API。

拦截器,onPrepareStatment() 无法使用,因为参数不可见。 在数据库上使用分区和可能的其他选项目前超出了范围,因为我们希望在此工作阶段避免特定于数据库的优化。

知道如何操纵休眠以提高性能吗?

【问题讨论】:

  • 您能否说得更清楚些 - 给出现在生成的 SQL 查询以及可以带来更好性能的变体。
  • 底层数据库是什么?我猜它不会是 Oracle,因为它通常将谓词下推到子选择和联合中...C1 在两个表中都有适当的索引吗?
  • C1 在两个表上都有索引。我们最终可能会支持多个 DB,其中包括 Derby (Pure java)。因此,当前的重点是定义一个可为所有数据库带来最佳性能的模式。

标签: hibernate jpa union-subclass


【解决方案1】:

我不建议您使用 table-pr-class 和许多或巨大的多态查询,但您想要更高的跨数据库性能。鉴别器列通常会更好。

请注意,如果您的类层次结构中有两个以上的级别,则可以将 table-pr-class 与 discrimantor-columns 结合使用。

【讨论】:

  • 感谢您的回答。然而,我试图通过拆分表来避免在 99% 的情况下不需要 90% 的数据的巨大表。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-29
  • 2013-01-07
  • 2013-04-01
  • 2019-05-04
  • 2013-11-08
  • 2017-12-10
相关资源
最近更新 更多