我今天一直在寻找答案,似乎最好的方法在某种程度上分歧。
我需要使用JDBC从Oracle数据库中检索150,000条记录。是否更好地使用一个select
查询检索数据并允许JDBC驱动程序使用Oracle游标和默认fetchSize
来处理从数据库传输记录 - 或者使用OR将查询拆分为批次LIMIT / OFFSET
?
使用LIMIT / OFFSET
选项,我认为专业人员可以控制每个块中返回的结果数量。缺点是查询被执行多次,您还需要使用相同的查询预先运行COUNT(*)
来计算所需的迭代次数。
一次检索所有内容的优点是您依靠JDBC驱动程序来管理从数据库中检索数据。缺点是有时可以忽略setFetchSize()
提示,这意味着我们最终会得到一个包含所有150,000条记录的巨大resultSet
!!
很高兴听到一些解决类似问题的真实生活经历,我们将非常感谢您的推荐。
答案 0 :(得分:0)
Oracle JDBC中的本机方式是使用async/await
进行查询prepareStatement
和获取
在循环中定义executeQuery
是的,当然,细节依赖于Oracle数据库和JDBC驱动程序版本,在某些情况下还需要fetchSize
可以忽略。但典型的问题是所需的提取大小被重置为fetchSize
,并且您有效地为每条记录进行往返。 (并不是说你一次得到所有记录)。
fetchSize = 1
的替代方案似乎对第一个视图有意义。但是如果您调查实现,您将决定不使用它。
假设您将结果集分成15个块,分别为10K:
您打开15个查询,每个查询平均有一半的资源消耗作为原始查询(LIMIT
选择数据并跳过它们)。
因此,你唯一能想到的就是处理时间会增加7倍以上。
最佳实践
接受您的查询,使用JDBC提取编写一个简单的脚本,使用10046跟踪查看有效使用的提取大小。 测试一系列的取尺寸并观察其性能;选择最佳的。
答案 1 :(得分:-1)
我的首选是保持安全的执行时间,如果被打断就能继续。我更喜欢这种方法,因为它是未来的证明并且尊重内存和执行时间限制。记住你今天没有计划,你计划在未来6米。今天150,000可能是6个月内的150万。
我使用长度为+ 1的食谱来了解是否还有更多要提取的内容,尽管如果重要的话,计数查询将允许您以%为单位执行进度条。
当考虑150,000记录结果集时,这是一个记忆压力问题。这取决于每行的平均大小。如果它是一个有三个整数的行,那就很小。如果它是一行包含一堆文本元素来存储用户配置文件的详细信息,那么这可能非常大。所以要谨慎对待你所从的领域。
还需要询问 - 您可能不需要一直提取所有记录。应用同步模式可能很有用。仅用比最后一次拉动更新的日期来拉取记录。