2009-05-05 93 views
3

我正在對postgresql數據庫中的表運行查詢。數據庫位於遠程機器上。該表有大約30個使用postgresql partitioning capability的子表。postgresql查詢上的大型結果集

該查詢將返回一個大型的結果集,大約有180萬行。

在我的代碼中,我使用spring jdbc支持,方法JdbcTemplate.query,但我的RowCallbackHandler未被調用。

我最好的猜測是postgresql jdbc驅動程序(我使用版本8.3-603.jdbc4)在調用我的代碼之前在內存中累積結果。我認爲fetchSize configuration可以控制這一點,但我試了一下,沒有任何改變。我做了這個postgresql手冊recomended

當我使用Oracle XE時,此查詢正常工作。但是我正在嘗試遷移到postgresql,因爲分區功能在Oracle XE中不可用。

我的環境:

  • PostgreSQL 8.3版本
  • Windows Server 2008企業64位
  • JRE 1.6 64位
  • 春2.5.6
  • PostgreSQL JDBC驅動8.3-603
+0

您的電話正在返回嗎?如果沒有,你嘗試了ctrl- \(Windows的ctrl-break),jstack,jconsole,visualvm或類似的找到線程停止的地方? – 2009-05-05 22:08:40

+0

它正在處理驅動程序內部的查詢。 – tuler 2009-05-06 00:25:30

+0

另請參見https://stackoverflow.com/a/47517489/32453 – rogerdpack 2017-11-27 19:56:36

回答

4

爲了使用遊標檢索數據,除了設置獲取大小之外,還必須將ResultSet.TYPE_FORWARD_ONLY(缺省值)的ResultSet類型和autocommit設置爲false。在您鏈接到的文檔中引用了該內容,但您沒有明確提及您執行了這些步驟。

請注意PostgreSQL的分區方案。它確實對優化器做了非常可怕的事情,並且在不應該存在的情況下可能會導致嚴重的性能問題(取決於您的數據的具體情況)。無論如何,你的行只有1.8M行嗎?沒有理由認爲它需要根據大小進行分區,因爲它被適當地編入索引。

2

我敢打賭,你的應用沒有一個客戶端這需要180萬行同時。你應該想到一個合理的方法將結果分成較小的部分,並給用戶遍歷它們的機會。

這就是Google所做的。當您進行搜索時,可能會有數百萬次點擊,但他們一次返回25頁,並且您可以在第一頁中找到想要的內容。

如果它不是一個客戶端,並且以某種方式處理結果,我建議讓數據庫收緊所有這些行並簡單地返回結果。僅僅爲了在中間層上進行計算而返回1.8M行是沒有意義的。

如果這些都不適用,你就有一個真正的問題。是時候重新思考了。

在閱讀後面的回覆之後,我覺得這更像是一種報告解決方案,應該批量處理或實時計算並存儲在不屬於事務處理系統一部分的表中。沒有辦法將180萬行數據帶到中間層來計算移動平均數。

我建議您重新定位自己 - 開始將其視爲報告解決方案。

2

fetchSize屬性的工作方式如postgres manual所述。

我的錯誤是我將auto commit = false設置爲來自連接池的連接,該連接池不是準備好的語句所使用的連接。

感謝您的所有反饋。

0

我做了上面的所有事情,但我需要最後一塊:確保調用包裝在事務中,並將事務設置爲只讀,以便不需要回滾狀態。

我加了這一點:@Transactional(readOnly = true)

乾杯。