Java jdbc数据集是否将所有行存储在jvm内存中
我正在使用JavaJDBC应用程序从数据库中获取大约500000条记录。正在使用的数据库是Oracle。我在获取每一行后立即将数据写入文件。由于完成整个数据的获取大约需要一个小时,因此我正在尝试增加结果集的获取大小。我在多个链接中看到,在增加获取大小时,应该注意内存消耗。增加获取大小是否确实会增加jvm使用的堆内存?Java jdbc数据集是否将所有行存储在jvm内存中,java,oracle,performance,jdbc,Java,Oracle,Performance,Jdbc,我正在使用JavaJDBC应用程序从数据库中获取大约500000条记录。正在使用的数据库是Oracle。我在获取每一行后立即将数据写入文件。由于完成整个数据的获取大约需要一个小时,因此我正在尝试增加结果集的获取大小。我在多个链接中看到,在增加获取大小时,应该注意内存消耗。增加获取大小是否确实会增加jvm使用的堆内存? 假设fetch大小为10,并且程序查询总共返回100行。在第一次获取期间,结果集包含10条记录。读取前10条记录后,resultset将获取下10条记录。这是否意味着在第二次提取之
假设fetch大小为10,并且程序查询总共返回100行。在第一次获取期间,结果集包含10条记录。读取前10条记录后,resultset将获取下10条记录。这是否意味着在第二次提取之后,数据集将包含20条记录?之前的10条记录是否仍保留在内存中,或者在获取新的批处理时是否将其删除?
感谢您的帮助。视情况而定。不同的司机可能表现不同,不同的司机可能表现不同
如果您有一个
CONCUR\u READ\u ONLY
,FETCH\u FORWARD
,TYPE\u FORWARD\u ONLY
ResultSet
,驱动程序几乎肯定会在内存中主动存储与您的提取大小对应的行数(当然,早期行的数据将在内存中保留一段时间,直到被垃圾回收)。另一方面,如果您的类型\u SCROLL\u不敏感
结果集
,则驱动程序很可能会将提取的所有数据存储在内存中,以便允许您在数据中前后滚动。这不是实现此行为的唯一可能方式,因此不同的驱动程序(和不同版本的驱动程序)可能有不同的行为,但这是最简单的,也是我遇到的大多数驱动程序的行为方式。在增加提取大小可能有助于提高性能的同时,我还将研究调整SDU大小,它控制sqlnet层数据包的大小。增加SDU大小可以加快数据传输
当然,获取这500000行所需的时间在很大程度上取决于您获取的数据量。如果需要一个小时,我猜您正在获取大量数据,并且/或者您正在通过WAN从远程客户端执行此操作
要更改SDU大小:
首先,通过在服务器的sqlnet.ora中更改或添加以下行,将服务器上的默认SDU大小更改为32k(从11.2.0.3开始,您甚至可以使用64kB,从12c开始,最多可以使用2MB):
默认大小=32767
然后修改您的JDBC URL:
jdbc:oracle:thin:@(DESCRIPTION=(SDU=32767)(HOST=…)(PORT=…)(CONNECT_DATA=Oracle驱动程序将只保存内存中由fetchSize定义的行数。因此,第一次提取的行将在第二次提取完成时被释放并被垃圾收集。但是500.000行的一个小时似乎非常慢。您确定受提取限制,而不是受语句本身限制吗?状态是否如果您在SQL*Plus中使用
set autotrace traceonly
,请运行一小时。您应该测量executeQuery()
和第一个ResultSet.next()之间的时间
call-我的猜测是,您正在等待Oracle准备查询结果是的,一个小时包括所有查询结果的获取。我希望增加获取大小可以减少总体获取时间。我执行的result语句从internet从外部db获取数据,我开始从数据库写入本地文件resultset开始写入,但每当internet断开连接时,写入就会中断。是因为resultset获取数据并动态写入文件吗?