我們目前正在研究加快我們的應用程序的方法,其中很大一部分與實體列表(實際上是一個表)有關。休眠分頁的數據加入分頁
參數和要求
該列表中的參數和要求如下(我將在這裏只提及相關的):
- 最多可以有50萬行/列表中的實體。
- 一次只顯示其中的幾個,我們將在這裏使用分頁。
- 用戶可以選擇要在列表中顯示哪些列(因此我們無法提供單個「靜態」查詢)。
- 大多數列表列都是可排序和/或可過濾的。
- 實體有一對多關係,它們也提供了一些列表列。
- 其中一些列表中的列可以包含多個值(這些被顯示爲列表中的單個細胞內)
- 從當前用戶的行爲始發的數據的任何更新(例如編輯,上傳等)應在被反射名單越好(即「immeditately」)
快,使模型更清楚一點考慮以下簡化實體(如JPA)模型:
class Car {
String manufacturer;
String model;
Date dateOfProduction;
List<TyreSize> allowedTyreSizes;
Set<Date> inspectionDates;
}
請不要嘗試因爲它是ju,所以對這個模型有着太多的意義st意在說明問題(我們的數據是不同的,而且更復雜)。然後
「完整的」汽車名單看起來是這樣的:
+==============+=======+=======+===============+=============+
| Manufacturer | Model | Prod. | Allowed Tyres | Inspections |
+==============+=======+=======+===============+=============+
| BMW | 320d |01/2016| - 225/40 R18 | - 01/07/16 |
| | | | - 225/45 R17 | - 13/12/16 |
+--------------+-------+-------+---------------+-------------+
| Toyota | Camry |09/2016| - 185/70 R13 | - 31/12/16 |
+--------------+-------+-------+---------------+-------------+
由於用戶可以選擇在運行時顯示的列我們動態地建立必要的查詢。到目前爲止,這一切都工作得很好。
基本問題
排序和過濾時參與我們遇到的問題是性能:我們目前的做法是裝載必需的排序和篩選到內存中的所有數據,做分類和過濾那裏,然後保留這些已排序的ID和頁面的列表。我們知道這有點慢,但迄今爲止表現足以滿足我們的管理。事情發生了變化,因爲我們現在有更多的數據可以操作,性能要求也提高了。
因此,我們正在研究如何改善所有的數據ADN的排序和篩選,而我們目前正在下面做對數據庫的方法,我還是會問這個(邊)問題:
- 如何最好地接近具有動態列的大量行以及每個單元可能具有多個值的分頁?
目前我們正在使用Postgresql,並希望儘可能繼續使用它,但如果不同的存儲更適合,我們至少會檢查出來。
目前的做法和問題(S)(底部)
正如上文所述,我們目前正在試圖讓數據庫排序,過濾和分頁我們的數據。可以使用2個查詢:一個用於獲取當前頁面的行標識,另一個用於實際加載這些行的數據。
由於面臨的挑戰是,我會集中在第一查詢:
據我所知,我們可以做在SQL這樣的事情(使用上面的車爲例):
SELECT DISTINCT id FROM (
SELECT id, ... FROM car c
LEFT OUTER JOIN allowedtyresizes ats ON c.id = ats.car_id
LEFT OUTER JOIN tyresizes ts ON ts.id = ats.tyresize_id
... //additional joins if required
ORDER BY ... //apply any user-defined sorts
WHERE ... //apply any user-defined filters (or maybe put them into the joins)
)
OFFSET ... //page offset
LIMIT ... //page size
從理論上講這個查詢(它可能不完全正確)應該提供我們需要的結果以確定爲當前頁面加載哪些行。
由於我們使用Hibernate(5.2 atm),我們希望使用HQL或Criteria來實現這一點。但是,好像Hibernate不支持從上面的select語句中選擇,因此這可能不是一個可行的方法。如果我們不得不退回到原生SQL或完全不同的方法,那麼我們寧願讓它適用於當前的基礎架構。
所以問題是:
- 不休眠5.x的支持,有點像「從選擇中選擇」?
- 當對多對多關係進行排序和過濾時,如何在單個連接可能導致重複行時使用Hibernate進行分頁?
你運行SQL查詢使用HQL通過傳遞你的查詢到字符串 –
@GauravSrivastav是的,我們知道如何執行SQL查詢,如果沒有更好的方法,我們將使用它。但是,由於查詢可能變得相當複雜並且動態創建,我們寧願不必訪問實體的映射信息來提取構建此類查詢所需的信息 - 而不是如果Hibernate已經提供了我們可以使用的東西。 – Thomas
你的模型有多複雜?通過使用數據庫視圖並將實體與它們綁定,您可能會獲得最佳性能。壞處是你需要手寫數據庫視圖(如果你開始支持新的RDBMS,可能還需要另一個版本)。好的是,實體會變得更簡單,而Hibernate生成性能較差的SQL的機會會更少。 –