Hibernate 6 连接继承查询性能与 Hibernate 5

问题描述 投票:0回答:1

我有一个像这样的实体模型:

class Article {
    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    public Set<UserPropertyValue<?>> getUserPropertyValues() {
        return userPropertyValues;
    } 
}

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class UserPropertyValue<T> {
   
}

@Entity
public class IntegerUserPropertyValue extends UserPropertyValue<Integer> {
}

@Entity
public class StringUserPropertyValue extends UserPropertyValue<String> {
}

// about 10 more inheritors like this, removed for clarity

现在,当我在 Hibernate 5 中运行

article.getUserPropertyValues()
时,我得到这个 PostgreSQL 查询(为了清晰起见,进行了删减):

select long_list_of_fields
from Article_UserPropertyValue userproper0_
inner join
UserPropertyValue userproper1_ on userproper0_.userPropertyValues_id = userproper1_.id
left outer join
IntegerUserPropertyValue userproper1_2_ on userproper1_.id = userproper1_2_.id
left outer join
StringUserPropertyValue userproper1_10_ on userproper1_.id = userproper1_10_.id
where userproper0_.Article_id = ?

在具有大约 2M UserPropertyValue 记录的数据库上,运行时间为 50 毫秒,并使用索引扫描。

现在我们正在升级到 Hibernate 6,我收到以下查询:

select long_list_of_fields
from Article_UserPropertyValue upv1_0
    join
    (
        UserPropertyValue upv1_1
        left join
        IntegerUserPropertyValue upv1_3 on upv1_1.id = upv1_3.id
        left join
        StringUserPropertyValue upv1_11 on upv1_1.id = upv1_11.id
    )
on upv1_1.id = upv1_0.userPropertyValues_id
where upv1_0.Article_id = ?

注意 Hibernate 现在如何连接子查询,而不是直接将所有子表连接到主表。

PostgreSQL 查询规划器中的某些内容决定对表 UserPropertyValue 进行顺序扫描。

有人知道有一些神奇的设置可以恢复到旧的行为吗?

java postgresql hibernate
1个回答
0
投票

回答我自己的问题;我没有找到改变 Hibernate 查询的方法,但我确实在 PostgreSQL 中找到了一个设置来修复新连接语法的性能。

join_collapse_limit
从默认值 8 增加到 50,使执行时间与旧语法保持一致。我有 12 个连接表(为简洁起见编辑了示例),我认为这导致优化器使用顺序扫描。

© www.soinside.com 2019 - 2024. All rights reserved.