2011-07-19 134 views
0

我在數據庫中有很多行,必須處理它,但由於內存限制,我無法將所有數據檢索到內存。什麼是從數據庫檢索連續數據的最快方法?

目前,我使用LIMIT和OFFSET檢索數據以獲取某些特定時間間隔內的數據。

我想知道如果是更快的方法或有另一種方法來從數據庫中的表中獲取所有數據。沒有過濾器將被應用,所有的行將被處理。

回答

5
SELECT * FROM table ORDER BY column 

沒有理由將整個表吸入RAM中。只需打開一個光標並開始閱讀。你可以玩取遊戲大小的遊戲而不是,但是數據庫會在你處理你的行的時候高興地保持它的位置。

附錄:

好吧,如果你使用的是Java,然後我有一個好主意,你的問題是什麼。

首先,通過使用Java,您正在使用遊標。這基本上是Java中的ResultSet。一些結果集比其他結果集更靈活,但其中99%是簡單的,只轉發ResultSet,您可以調用'next'來獲取每一行。

現在就你的問題。

問題出在Postgres JDBC驅動上。我不知道他們爲什麼要這樣做,或許它是規範,也許是別的,但無論如何,Postgres具有奇特的特點,即如果Connection的autoCommit設置爲true,則Postgres決定吸取整個結果集執行方法或第一個下一個方法。對於哪裏來說並不重要,只有如果你有一個巨大的行,你會得到一個很好的OOM異常。沒有幫助。

這可以很容易地正是你所看到的,我很欣賞它是如何相當令人沮喪和困惑。

大多數連接默認爲autoCommit = true。相反,只需將autoCommit設置爲false即可。

Connection con = ...get Connection... 
con.setAutoCommit(false); 
PreparedStatement ps = con.prepareStatement("SELECT * FROM table ORDER BY columm"); 
ResultSet rs = ps.executeQuery(); 
while(rs.next()) { 
    String col1 = rs.getString(1); 
    ...and away you go here... 
} 
rs.close(); 
ps.close(); 
con.close(); 

註明顯缺乏異常處理,作爲練習留給讀者。

如果你想在多少行時間到內存中被取更多的控制,你可以使用:

ps.setFetchSize(numberOfRowsToFetch); 

與周圍玩可能會提高你的表現。

如果您關心排序,請確保您在ORDER BY中使用的列上有適當的索引。

+0

什麼是遊標?這是如何工作的? –

+0

http://www.postgresql.org/docs/current/static/sql-declare。html –

+0

我可以檢索遊標到Java並獲取數據嗎? –

相關問題