2011-07-19 61 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并获取数据吗? –

相关问题