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