2016-03-08 35 views
2

有一個similar question about streaming large results但答案只是指向文檔,並沒有明確的答案出現。 我認爲,僅僅treating a full result set as a stream仍然需要大量內存的JDBC驅動側..真正流式傳輸大型MySQL結果集

我想知道是否有任何明確的模式,或最佳實踐,爲使其工作,特別是在JDBC驅動程序的一面。

特別是我不確定爲什麼setFetchSize(Integer.MIN_VALUE)是一個非常好的想法,因爲如果這意味着每行都是在電線上自行發送的話,那麼它看起來遠非最佳。

我相信像jooq和slick這樣的圖書館已經在照顧這個......並且很好奇如何在沒有它們的情況下完成它。

謝謝!

+0

P.S.有些東西與postgres相關並且特定於使用slick的問題:http:// stackoverflow。com/questions/31340507/what-is-the-right-way-to-work-with-slicks-3-0-0-streaming-results-and-postgresq – matanster

+0

The documentation(http://dev.mysql.com /doc/connector-j/en/connector-j-reference-implementation-notes.html)表示要麼一切都加載到內存中,要麼一行一行地檢索行。其他數據庫驅動程序更安全。 –

+0

嗯,我不確定它是真的明確,在這些文件中,這些是唯一的選擇..你確定嗎? – matanster

回答

1

我想知道是否有任何清晰的模式,或最佳實踐,使其工作,尤其是在jdbc驅動程序方面。

最好的做法是不要做同步串流,而是取得中等大小的塊。但是請避免使用OFFSET(也是see)。如果您正在執行批處理過程,可以通過首先選擇數據並將其推送到臨時表中(例如,先將您想要的原始結果轉換爲表格中的表格,然後從表格中選擇塊...數據庫在複製數據時真的很快內部)。

同步串流一般不會縮放(又名迭代器)。它不能很好地進行批量處理,它當然不能處理大量的客戶端。這就是爲什麼驅動因素各不相同,並且做了很多不同的事情,因爲它很難找出要裝載多少資源,因爲它是一個拉式模型。異步流(推模式)可能會有所幫助,但不幸的是,JDBC標準不支持異步流。

您可能會注意到,但這是爲什麼許多像JDBC Spring這樣的JDBC包裝器不會返回Iterator(以及需要手動清理資源的事實)的原因之一。一些包裝提供迭代器,但他們真的只是把結果變成一個列表。

您對Scala版本的鏈接相當令人不安,它的upvoted賦予了管理ResultSet的有狀態......它的非Scala像......我不確定那些人知道他們必須使用迭代器或者正確關閉連接/ ResultSet,這需要大量的命令式編程。

儘管讓數據庫決定要緩衝多少似乎效率不高,但要記住,大多數數據庫連接在內存方面都非常重要(至少在postgres上)。因此,如果您需要花費很長時間進行流媒體處理並擁有許多客戶端,則必須創建更多連接並給數據庫帶來嚴重負擔。更不用說默認緩衝區可能已經被高度優化(即客戶端最終的結果集大小)。

最後,對於批處理,可以並行執行塊,這顯然比同步管道更有效,並且在發生問題時重新啓動(無需重新處理已處理的數據)。