2009-06-29 57 views
2

當前正在部署基於OFBiz的ERP,我們遇到了以下問題:框架的一些代碼調用resultSet.last()來了解結果集的總行數。使用Oracle JDBC Driver v11和v10,它會嘗試緩存客戶機內存中的所有行,導致JVM崩潰,因爲它沒有足夠的堆空間。Oracle是否通過JDBC支持服務器端可滾動遊標?

經過研究,問題似乎是Oracle JDBC通過使用緩存在客戶端而不是服務器中實現Scrollable Cursor。使用datadirect驅動程序,該問題已解決,但似乎對resultset.last()的調用需要太多才能完成,因此應用程序服務器會中止事務

是否有任何方法通過jdbc實現可滾動遊標oracle而不訴諸於datadirect驅動程序?

什麼是知道給定結果集長度的最快方法?

在此先感謝 伊斯梅爾

+0

我會先問一個切線問題;你同時需要結果集的數據和大小,還是隻需要執行一個COUNT(*)類型的查詢來查找行數?你是否真的需要行數呢?我曾多次看到過這樣的情況:如果程序在真正不需要的時候花費很多時間獲取分頁行的總數,那麼這種情況非常昂貴。 – Gandalf 2009-06-29 21:32:02

+0

需要確定分頁方案中的頁數。我們試圖避免使用last,並使用iterator next()方法檢查null來計算currentIndex。有沒有一種快速的方法來知道沒有使用last()方法的頁數。 我們的解決方法是使用相同的條件執行COUNT查詢,然後執行數據查詢 – Ismael 2009-06-29 22:04:42

回答

1

「什麼是知道一個給定的結果集的長度以最快的方式」 只有這樣,才能真正知道是指望他們所有。你想知道電話簿中有多少個'SMITH'。你數它們。 如果它是一個小的結果集,並很快到達,這不是問題。 EG電話簿中不會有很多Gandalfs,你可能想要把它們全部拿回來。

如果它是一個較大的結果集,您可能可以進行估計,但這通常不是SQL精心設計的。

以避免緩存整個結果在客戶端設置,你可以嘗試

select id, count(1) over() n from junk; 

然後每一行都會有一個額外的列(在這種情況下,n)與行的結果集數。但它仍然需要花費相同的時間來計算,所以仍然有很大的超時時間。

妥協是得到第一百(或千)行,不要擔心分頁以外的分頁。

0

您提議的「解決方法」與計數基本上使數據庫服務器完成的工作翻倍。它必須首先遍歷所有內容來計算結果數量,然後執行相同的+返回結果。 Gary提到的方法(count(*)over() - analytics)更好。但即使在這裏,整個結果集也必須在第一個輸出返回給客戶端之前創建。所以它可能會減慢大容量輸出的內存消耗。

我認爲最好的辦法是在屏幕上只選擇你想要的頁面(+1來確定下一個存在)例如從21到41行。並有另一個按鈕(用例)來統計他們所需要的(罕見)情況。