我們目前正在使用 cockroach DB,但由于缺乏游標支持,它不支持一次回傳 X 記錄。這意味著當嘗試流式傳輸大量(約 1000 萬)記錄時,資料庫會回傳一個完整的 ResultSet,導致應用程式因記憶體不足而崩潰。
Cockroach 建議使用分頁(最好是鍵集)來檢索大量結果,但是有沒有一種很好的方法可以讀取所有頁面并回傳一個 Stream,而無需在任何時候將所有結果加載到記憶體中?
謝謝!
uj5u.com熱心網友回復:
只要您沒有在同一個連接上同時發生多個操作,您就應該能夠設定 JDBC fetchSize 屬性并控制回傳多少結果。
uj5u.com熱心網友回復:
由于供應商檔案建議...
鍵集分頁查詢的一般模式是:
SELECT * FROM t AS OF SYSTEM TIME ${time} WHERE key > ${value} ORDER BY key LIMIT ${amount}這比使用 LIMIT/OFFSET 更快,因為不是對 OFFSET 的值進行全表掃描,而是鍵集分頁查詢在每次迭代時查看固定大小的記錄集。如果 WHERE 子句中用于實作分頁的鍵是索引的并且是唯一的,則可以快速完成此操作。主鍵滿足這兩個條件。
注意:CockroachDB 沒有游標。要支持類似游標的用例,即“在打開游標的那一刻對資料庫的快照進行操作”,請使用
AS OF SYSTEM TIME以下示例中所示的子句。
這意味著或用戶(界面)提供或“我們”存盤:
$value,它指的是每個分頁請求的“最后看到的鍵”(/session!)
此外,如果我們想要“類似游標”的行為,我們需要提供/存盤:
${time},它指的是最后一個請求(/會話)分頁時間戳。
當我們提供附加引數時,我們可以在一個存盤庫查詢中完成所有操作:
public interface SomeRepository extends JpaRepository<Some, Long> {
@Query(
value = """
SELECT * FROM SOME [, ....]
AS OF SYSTEM TIME follower_read_timestamp()
[JOIN ...]
WHERE [... AND] some.ID > :lastKey
ORDER BY some.ID
"""
// If you want/need the count
countQuery = "SELECT count(*) FROM <[SAME_QUERY]>",
nativeQuery = true)
// Pageable if you know the total size, Slice otherwise ;)
Pageable<Some> findCustom(/* more paramas?, */
@Param("lastKey") Long lastKey, Pageable pageable);
// done(?;)
}
...并保持謹慎的希望,只pageable.pageSize獲取專案(從資料庫和加載到記憶體)。
一些參考:
- SDJ 本地查詢
- SDJ 分頁和排序
- SDJ 命名引數
AS OF SYSTEM TIME
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/363960.html
上一篇:如何進行良好的JPA查詢
