52 java sql-server jdbc
我有这个非常大的桌子,每天有数百万条记录,每天结束时我都会提取前一天的所有记录.我这样做:
String SQL = "select col1, col2, coln from mytable where timecol = yesterday";
Statement.executeQuery(SQL);
Run Code Online (Sandbox Code Playgroud)
问题是这个程序需要2GB的内存,因为它会将所有结果都记在内存中然后处理它.
我尝试设置Statement.setFetchSize(10)
但它从操作系统获取完全相同的内存它没有任何区别.我正在使用Microsoft SQL Server 2005 JDBC驱动程序.
有没有办法以小块的形式读取结果,比如Oracle数据库驱动程序执行查询时只显示几行,当你向下滚动时会显示更多结果?
Dar*_*gue 65
在JDBC中,该setFetchSize(int)
方法对于JVM中的性能和内存管理非常重要,因为它控制从JVM到数据库的网络调用的数量,以及相应的用于ResultSet处理的RAM量.
本质上,如果调用setFetchSize(10)并且驱动程序忽略它,则可能只有两个选项:
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中验证).
ska*_*man 25
该fetchSize
参数是JDBC驱动程序的提示,指示要从数据库中一次获取的许多行.但是司机可以自由地忽略这一点并做它认为合适的事情.某些驱动程序(如Oracle的驱动程序)以块的形式获取行,因此您可以读取非常大的结果集而无需大量内存.其他驱动程序只需一次读取整个结果集,我猜你的驱动程序正在做什么.
您可以尝试将驱动程序升级到SQL Server 2008版本(可能更好)或开源jTDS驱动程序.
jwa*_*ell 14
您需要确保关闭 Connection上的自动提交,否则setFetchSize将不起作用.
dbConnection.setAutoCommit(false);
Run Code Online (Sandbox Code Playgroud)
编辑:记得当我使用此修复程序时它是Postgres特定的,但希望它仍然适用于SQL Server.
报表接口Doc
总结:
void setFetchSize(int rows)
当需要更多行时,向 JDBC 驱动程序提供有关应从数据库中提取的行数的提示。
阅读这本电子书J2EE 及更高版本 作者:Art Taylor
归档时间: |
|
查看次数: |
88502 次 |
最近记录: |