我是JPA/JPQL的新手,所以請原諒,如果這個問題不明確。用於檢索複雜實體的高效JPQL查詢
我正在嘗試查找高效的JQPL查詢以獲取複雜對象的所有記錄。
(即,由多個表來表示,與幾個一對多的關係 - 見以下簡化的例子):
class ComplexObject {
private Set< SubOject1> so1 ...
.....
@OneToMany(fetch = FetchType.LAZY)
public Set< SubOject1>...
}
class SubObject1 {
private Set< SubOject2> so2 ...
.....
@OneToMany(fetch = FetchType.LAZY)
public Set< SubOject2>...
}
我使用以下JPQL查詢:
select distinct CO
from ComplexObject CO
left join fetch CO.so1 SO1
left join fetch SO1.so2
的查詢在無狀態會話上運行,以便獲取DB中當前數據的實際快照,該數據與實體管理器分離(因此使用左連接提取)。
不幸的是,我遇到兩個問題:
由於複雜的對象包含SO1的多個實例,每個實例SO1 SO2包含的多個實例,底層轉換爲SQL查詢生成特定選擇查詢每行所有表連接的產品 - 非常浪費的解決方案。有沒有辦法減少內部選擇查詢的數量? (這看起來像可怕的N + 1查詢問題)。
JPQL查詢返回所有表連接的產品上的每個內部SQL查詢的ComplexObject實例 - 這意味着對ComplexObject實例的多個引用。爲什麼這會發生在'select distinct'查詢上?
編輯:只是澄清 - 我使用的JPA框架是hibernate,而數據庫是HyperSQL。
編輯:(1)問題結果與使用p6spy日誌框架相關,p6spy日誌框架打印出大型數據庫表中的所有結果。記錄格式導致了許多查詢在哪裏執行的錯誤假設。
在嘗試微調性能時,使用本機查詢似乎沒有比使用JPQL查詢更好的性能。 使用本機查詢還會導致Object typed結果,這需要後處理。
最有效的查詢是類型化的本地查詢。如果您不能忍受Hibernate(或其他ORM)開銷,那麼不要使用Criteria或JPQL查詢。 –
@Baldurian:使用JPQL的一般概念是爲了在一個事務中獲取大部分數據庫數據有問題嗎? (即,在這種情況下應該使用原生查詢) –
如果類型化原生查詢更有效,那麼標準或JPQL查詢的效率如何?大多數已命名查詢的處理都可以事先完成,並且根據查詢本身,無論是本機還是JPQL,都可以同樣高效或低效。原生查詢允許自定義,但大多數JPA提供商提供了一系列可以提高性能的選項,如果您知道自己在做什麼。 – Chris