JDBC ResultSet 获取大型数据集的内部机制



JDBC 结果集是否在一次网络调用中获取 SQL 查询中的所有数据?考虑查询select * from table where timestamp > 1597937895。现在此查询有超过 100 万行。结果集是否提取一个网络调用中的所有行?还是在读取结果集时获取一批行?因为我还需要查看内存使用情况。因此澄清。众所周知,ResultSet 在一个网络调用中获取所有数据。这是唯一的行为,还是有其他方法可以告诉结果集批量获取数据?

读取行和批处理的确切行为因数据库系统和驱动程序而异。有些将始终批处理,有些将 - 默认情况下 - 一次获取所有行,对于某些行,这取决于结果集类型或其他因素。

默认情况下,MySQL 连接器/J 驱动程序将在执行时获取内存中的所有行。这可以使用批大小更改为行流或基于游标的读取,如 JDBC API 实现说明中">结果集"下所述:

默认情况下,结果集完全检索并存储在内存中。 在大多数情况下,这是最有效的操作方式,并且由于 MySQL网络协议的设计,更容易实现。如果 您正在使用具有大量行的结果集或 较大的值,无法在 JVM 中为内存分配堆空间 必需,您可以告诉驱动程序将结果流式传输回一行 一次。

要启用此功能Statement,请在 以下方式:

stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,
java.sql.ResultSet.CONCUR_READ_ONLY); 
stmt.setFetchSize(Integer.MIN_VALUE); 

只进、只读结果集与读取的组合Integer.MIN_VALUE的大小用作驱动程序流式传输的信号 逐行生成结果集。在此之后,使用 语句将逐行检索。

[.. 但请阅读警告..]

另一种选择是使用基于游标的流式处理来检索集合 每次的行数。这可以通过设置连接来完成 属性useCursorFetch为 true,然后调用setFetchSize(int)int是每次要获取的所需行数:

conn = DriverManager.getConnection("jdbc:mysql://localhost/?useCursorFetch=true", "user", "s3cr3t");
stmt = conn.createStatement();
stmt.setFetchSize(100);
rs = stmt.executeQuery("SELECT * FROM your_table_here");

相关内容

  • 没有找到相关文章

最新更新