3 回答
TA贡献1831条经验 获得超9个赞
在JDBC中,该setFetchSize(int)
方法对于JVM中的性能和内存管理非常重要,因为它控制从JVM到数据库的网络调用的数量,以及相应的用于ResultSet处理的RAM量。
本质上,如果调用setFetchSize(10)并且驱动程序忽略它,则可能只有两个选项:
尝试使用不同的JDBC驱动程序来支持fetch-size提示。
查看Connection上的驱动程序特定属性(创建Connection实例时的URL和/或属性映射)。
RESULT-SET是响应查询而在DB上编组的行数。ROW-SET是从JVM到DB的每次调用从RESULT-SET中取出的行块。处理所需的这些调用数和生成的RAM取决于fetch-size设置。
因此,如果RESULT-SET有100行且fetch-size为10,那么将有10次网络调用来检索所有数据,在任何给定时间使用大约10 * {row-content-size} RAM。
默认的fetch-size是10,相当小。在发布的情况下,似乎驱动程序忽略了fetch-size设置,在一次调用中检索所有数据(大RAM要求,最佳最小网络调用)。
下面发生的ResultSet.next()
是它实际上并没有从RESULT-SET一次获取一行。它从(本地)ROW-SET中获取它,并在本地客户端上耗尽时从服务器获取下一个ROW-SET(不可见)。
所有这一切都取决于驱动程序,因为设置只是一个“提示”,但实际上我发现这是它如何适用于许多驱动程序和数据库(在许多版本的Oracle,DB2和MySQL中验证)。
TA贡献1934条经验 获得超2个赞
该fetchSize
参数是JDBC驱动程序的提示,指示要从数据库中一次获取的许多行。但是司机可以自由地忽略这一点并做它认为合适的事情。某些驱动程序(如Oracle的驱动程序)以块的形式获取行,因此您可以读取非常大的结果集而无需大量内存。其他驱动程序只需一次读取整个结果集,我猜你的驱动程序正在做什么。
您可以尝试将驱动程序升级到SQL Server 2008版本(可能更好)或开源jTDS驱动程序。
TA贡献1802条经验 获得超4个赞
您需要确保关闭 Connection上的自动提交,否则setFetchSize将不起作用。
dbConnection.setAutoCommit(false);
编辑:记得当我使用此修复程序时它是Postgres特定的,但希望它仍然适用于SQL Server。
添加回答
举报