我正在使用Java
从SQL RDBMS
读取并将结果返回给用户。问题是数据库表有155 Million rows
,这使得等待时间非常长。
我想知道是否可以检索结果,因为它们来自数据库并以递增方式呈现给用户(批量)。
我的查询很简单SELECT * FROM Table_Name query
。
在SELECT
查询完成之前,是否有机制或技术可以批量回放数据库记录?
使用的RDBMS是MS SQL Server 2008。
提前致谢。
答案 0 :(得分:1)
方法Statement#setFetchSize
和Statement#getMoreResults
应该允许您管理数据库中的增量提取。不幸的是,这是接口规范,供应商可能会也可能不会实现这些。获取期间的内存管理实际上取决于供应商(这就是为什么我不会严格地说“JDBC就像这样工作”)。
来自JDBC documentation on Statement :
setFetchSize(int rows)
给JDBC驱动程序一个关于应该是多少行的提示 当ResultSet需要更多行时从数据库中获取 本声明产生的对象。
getMoreResults可()
移动到此Statement对象的下一个结果,如果是a,则返回true ResultSet对象,并隐式关闭任何当前的ResultSet对象 用getResultSet方法获得。
getMoreResults(int current)
移动到此Statement对象的下一个结果,处理任何当前 ResultSet对象根据给定的指令 flag,如果下一个结果是ResultSet对象,则返回true。 当前参数表示保持或关闭当前ResultSet?
此外,这个SO response回答了关于SQLServer 2005使用setFetchSize
以及它似乎无法管理批量提取的问题。建议使用2008驱动程序对此进行测试,或者使用jTDS驱动程序(在评论中竖起大拇指)
此response to the same SO post也可能有用,因为它包含MSDN上SQLServer驱动程序设置的链接。
the MS technet website上还有一些很好的信息,但更多地与SQLServer 2005有关。在我粗略的评论中找不到2008特定版本。无论如何,它建议用:
创建Statementcom.microsoft.sqlserver.jdbc.SQLServerResultSet.TYPE_SS_SERVER_CURSOR_FORWARD_ONLY(2004)仅可转发,只读访问的可滚动性,然后使用setFetchSize方法调整性能
答案 1 :(得分:0)
使用分页(LIMIT pageno, rows
/ TOP
)可能会创建漏洞和重复项,但可能会与检查最后一行ID(WHERE id > ? ORDER BY id LIMIT 0, 100
)结合使用。
您可以使用TYPE_FORWARD_ONLY或FETCH_FORWARD_ONLY
。
答案 2 :(得分:0)
这正是JDBC驱动程序应该如何工作(我记得旧PostgreSQL驱动程序中的错误,导致所有获取的记录存储在内存中)。
但是,它使您能够在查询开始获取记录时读取记录。这是我开始搜索的地方。
例如,Oracle优化SELECT *
查询以获取整个集合。这意味着在第一个结果出现之前可能需要很长时间。您可以提供优化提示以获取第一个结果,这样您就可以非常快速地向用户显示第一行,但整个查询可能需要更长时间才能执行。
您应首先在控制台上测试您的查询,以检查它何时开始获取结果。然后尝试使用JDBC并在迭代ResultSet
时监视内存使用情况。如果内存使用量快速增长,请检查是否已在只进和只读模式下打开ResultSet,必要时更新驱动程序。
如果由于内存使用而无法使用此类解决方案,您仍然可以手动使用游标并在每个查询中获取N行(例如,100)。
MSSQL的游标文档:例如:http://msdn.microsoft.com/en-us/library/ms180152.aspx