Java MySQL Connector/J在“流式传输”结果集时是否缓冲行?

Java MySQL Connector/J在“流式传输”结果集时是否缓冲行?,java,mysql,jdbc,Java,Mysql,Jdbc,根据我的阅读,我发现使用MySQL JDBC驱动程序在MySQL中传输ResultSet的方法是以下两个命令: stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY); stmt.setFetchSize(Integer.MIN_VALUE); 我的问题是,专家能否澄清,使用上述代码对结果集进行流式处理是否会将一行返回给客户端,然后转到服务器获取

根据我的阅读,我发现使用MySQL JDBC驱动程序在MySQL中传输ResultSet的方法是以下两个命令:

stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY);
stmt.setFetchSize(Integer.MIN_VALUE);
我的问题是,专家能否澄清,使用上述代码对结果集进行流式处理是否会将一行返回给客户端,然后转到服务器获取下一行,等等,效率非常低,或者它是否足够聪明,可以像BufferedStreamReader那样进行缓冲流式处理?如果是缓冲流,如何设置缓冲区大小

编辑:从:

前向只读结果集与提取结果集的组合 Integer.MIN_值的大小用作向驱动程序发送流的信号 结果按行设置。在此之后,使用 语句将逐行检索

这是否意味着如果我有10M行,那么有10M次往返到服务器以获取这些行?这是非常低效的。如何流式传输结果集,但将其缓冲,以便不必进行如此多的往返

EDIT2:当fetchSize设置为Integer.MIN_值时,MySQL似乎会自动进行一些缓冲。在我的测试中,我能够使用setFetchSizeInteger.MIN_值在不到20分钟内读取超过40M行。这意味着每秒大约30000行。我不知道平均排数有多大,但很难想象每秒有30000次往返

还有一个单独的问题:如果结果集的元素多于fetchSize,MySQL会怎么做?e、 例如,结果集有10M行,fetchSize设置为1000。然后呢

当fetchSize设置为Integer.MIN_值时,MySQL似乎会自动执行一些缓冲

至少有时是这样。我使用Wireshark测试了MySQL连接器/J版本5.1.37的行为。为了桌子

创建表lorem id INT自动递增主键, 标签VARCHAR7, text1 VARCHAR255, text2varchar255 。。。有了测试数据

id标签text1 text2 -- ---- -------- -------- 0行\u 000 Lorem ipsum。。。乱数假文。。。 第1行第001页第1行。。。乱数假文。。。 第2行第002页第1行。。。乱数假文。。。 ... 999行_999Lorem ipsum。。。乱数假文。。。 其中,“text1”和“text2”实际上每行包含255个字符 。。。而代码

try语句s=conn.createStatementjava.sql.ResultSet.TYPE_FORWARD_ONLY,java.sql.ResultSet.CONCUR_READ_ONLY{ s、 setFetchSizeInteger.MIN_值; 字符串sql=按id从lorem ORDER中选择*; try ResultSet rs=s.executeQuerysql{ …就在s.executeQuerysql之后–即,甚至在调用rs.next之前–MySQL Connector/J从表中检索到了前140行

事实上,当只查询标记列时

字符串sql=按id从lorem ORDER中选择标记; MySQL Connector/J立即检索到所有1000行,如Wireshark网络帧列表所示:

将查询发送到服务器的第19帧如下所示:

MySQL服务器以第20帧响应,该帧以

…紧接着是第21帧,以

…以此类推,直到服务器发送了第32帧,该帧以

因为唯一的区别是每行返回的信息量,所以我们可以得出结论,MySQL Connector/J根据返回的每行的最大长度和可用的可用内存量来决定合适的缓冲区大小

如果结果集的元素多于fetchSize,MySQL会怎么做?例如,结果集有10M行,fetchSize设置为1000。然后会发生什么

MySQL Connector/J最初检索第一组fetchSize行,然后随着rs.next的移动,它最终将检索下一组行。即使对于setFetchSize1也是如此,顺便说一句,setFetchSize1是一次只获取一行的方法


请注意,n>0的setFetchSizen要求在连接URL中使用useCursorFetch=true。setFetchSizeInteger.MIN\u值显然不需要使用useCursorFetch。请检查此项。另一个有趣的read fetchsize定义了流媒体的缓冲区大小。是的,在这种情况下,缓冲区大小是1请重新阅读我的问题,看看您是否能够理解这里问的和其他地方问的有区别。是的,单词不同,但问题不一样。有趣的是,这似乎与文档中描述的内容不匹配,而且他们甚至忽略了提到useCursorFetch on。这确实让我怀疑useCursorFetch是否与使用Integer.MIN_值有相同的注意事项。是y吗您可以分享您如何使用Wireshark测试行为的详细信息吗?我可以问一下,这项深入研究/测试是针对哪个版本的驱动程序执行的吗?@matanster这些测试是使用MySQL Connector/J version 5.1.37执行的。