我想让hibernate生成一个连接,而不是一个用于查询集合的子选择,而不是可以使用FetchMode.JOIN配置的连接。
示例表:
root(id, property, <other_properties>)
layer1(id, root_id, <other_properties>)
layer2(id, layer1_id, <other_properties>)
layer3(id, layer2_id, <other_properties>)
以及与layer1-3处于同一级别的集合的其他表。取决于我获得的@Fetch(FetchMode.X)注释
FetchMode.JOIN:
SELECT *
FROM root r
LEFT OUTER JOIN layer1 L1 ON r.id=L1.root_id
LEFT OUTER JOIN layer2 L2 ON L1.id=L2.layer1_id
LEFT OUTER JOIN layer3 L3 ON L2.id=L3.layer2_id
WHERE r.property=?
这是一个包含大量重复数据的非常宽的结果集。 每个父母另外选择一个其他集合。 E.g。
SELECT ...
FROM other o
WHERE o.root_id = ?
FetchMode.SUBSELECT
稍微好一些,因为每个实体只有一个选择。因此,查询的数量受限定的实体数量而不是查询结果大小。
SELECT L3.*
FROM layer3 L3
WHERE L3.layer2_id IN (
SELECT L2.id
FROM layer2 L2
WHERE L2.layer1_id IN (
SELECT L1.id
FROM layer1 L1
WHERE L1.root_id IN (
SELECT r.id
FROM root r
WHERE r.property=?
)))
root和layer1表每个包含~50M条目,layer2和3个表每个~500M。这导致我们的Postgres DB上面的选择(~10分钟)的性能非常糟糕。
我可以让Hibernate生成一个“自下而上”的连接语句吗?
SELECT L3.* FROM layer3 L3
JOIN layer2 L2 ON L3.layer2_id = L2.id
JOIN layer1 L1 ON L2.layer1_id = L1.id
JOIN root r ON L1.root_id = r.id
where r.property = ?
此查询具有相同的结果,但可以在几毫秒内执行。
感谢。