javajdbc中的oracle分页
我有一张有数百万条记录的桌子。为了使系统更快,我需要在Java代码中实现分页概念。我一次只需要提取1000条记录并进行处理,然后再提取1000条记录并进行处理,以此类推。我已经尝试了一些方法,但没有一种有效。下面列出了我尝试过的一些事情-
1) String query = "select * from TABLENAME" + " WHERE ROWNUM BETWEEN %d AND %d";
sql = String.format(query, firstrow, firstrow + rowcount);
在上面的示例中,当查询为SELECT * from TABLENAME Where ROWNUM BETWEEN 0 and 10
时,它会给我一个结果,但当查询为SELECT * from TABLENAME Where ROWNUM BETWEEN 10 and 20
时,它会返回一个空的结果集。我甚至试着在数据库中运行它,它返回空的结果集(不知道为什么!!)
2)preparedStatement.setFetchSize(100);
我的Java代码中有这个,但它仍然从表中获取所有记录。添加此语句无论如何都不会影响我的代码
请帮忙
# 1 楼答案
在Oracle中实现分页的常规方法是使用分析窗口函数,例如^{} 和定义行顺序的
ORDER BY
子句。然后,使用分析函数的查询被包装到一个内联视图(或“窗口”)中,从中可以查询所需的行号。下面是一个从my_table
(按column_to_sort_by
排序)查询前1000行的示例:JDBC实现可以如下所示:
请注意,在读取该表时,该表应保持不变,以便分页在不同的查询执行中正确工作
如果表中的行太多,导致内存不足,可能需要在读取某些页面后清除/序列化列表
编辑:
如果行的顺序对您来说根本不重要,那么正如@bdrx在他的回答中提到的,您可能不需要分页,最快的解决方案是在
SELECT
中查询不带WHERE
条件的表。正如建议的那样,您可以将语句的获取大小调整为更大的值,以提高吞吐量# 2 楼答案
听起来你实际上不需要对结果进行分页,只需要批量处理结果。如果是这种情况,那么您需要做的就是使用setFetchSize将fetchSize设置为1000,并像往常一样迭代resultset(使用
resultset.next()
),并在迭代时处理结果。有很多资源描述setFetchSize及其功能。做一些研究:对于oracle分页,有很多资源描述了如何实现这一点。只需进行网络搜索。以下是一些资源,它们描述了如何做到这一点:
如果不定义一致的排序(
ORDER BY
子句),分页就不是很有用,因为不能依赖它们返回的顺序这个答案解释了
BETWEEN
语句不起作用的原因:https://stackoverflow.com/a/10318244/908961根据答案,如果使用早于12c的oracle,则需要进行子选择以获得结果。比如:
如果您使用的是Oracle 12c或更高版本,我建议您使用较新的}语法,而不是摆弄
OFFSET
{rownum
。请参阅上面或下面的第一个链接 http://www.toadworld.com/platforms/oracle/b/weblog/archive/2016/01/23/oracle-12c-enhanced-syntax-for-row-limiting-a-k-a-top-n-queries所以你的问题应该是
或者使用事先准备好的声明
或者,您也可以使用这里描述的limit关键字http://docs.oracle.com/javadb/10.10.1.2/ref/rrefjdbclimit.html,您的查询如下