java - 选择 HSQLDB 中 100 多百万行

标签 java jdbc prepared-statement hsqldb

我必须在 HSQLDB 数据库上使用 JDBC 迭代包含 100 多百万条记录的表,但我无法在合理的时间内完成它。我使用hsqldb v2.4.0。

我尝试使用 PreparedStatement 和以下查询来切片数据:

String select = "SELECT ID, NAME, VALUE FROM MY_TABLE ORDER BY ID OFFSET ? ROWS FETCH ? ROWS ONLY";

问题是我们浏览表格需要越来越多的时间。请注意,ID 列已建立索引。

我尝试输入获取大小,但它也不起作用:

String select = "SELECT ID, NAME, VALUE FROM MY_TABLE";
PreparedStatement selectStatement = connection.prepareStatement(select, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
selectStatement.setFetchSize(5000);

然后我迭代 ResultSet :

ResultSet result = selectStatement.executeQuery();
while (result.next()) {
    Long id = result.getLong(1);
    // do stuff ...
} 

HSQLDB 仍尝试获取表中的所有行,但返回的 ResultSet 无法放入内存。这是堆栈跟踪:

java.lang.OutOfMemoryError: Java heap space
at org.hsqldb.navigator.RowSetNavigatorData.ensureCapacity(Unknown Source)
at org.hsqldb.navigator.RowSetNavigatorData.add(Unknown Source)
at org.hsqldb.QuerySpecification.buildResult(Unknown Source)
at org.hsqldb.QuerySpecification.getSingleResult(Unknown Source)
at org.hsqldb.QuerySpecification.getResult(Unknown Source)
at org.hsqldb.StatementQuery.getResult(Unknown Source)
at org.hsqldb.StatementDMQL.execute(Unknown Source)
at org.hsqldb.Session.executeCompiledStatement(Unknown Source)
at org.hsqldb.Session.execute(Unknown Source)
at org.hsqldb.jdbc.JDBCPreparedStatement.fetchResult(Unknown Source)
at org.hsqldb.jdbc.JDBCPreparedStatement.executeQuery(Unknown Source)
at com.jolbox.bonecp.PreparedStatementHandle.executeQuery(PreparedStatementHandle.java:174)
at myclass at the line ResultSet result = selectStatement.executeQuery();

有没有办法在 HSQLDB 中实现这一点?

最佳答案

此问题与内存使用无关,因为此类 SELECT 不会使用太多内存。

预计选择结果的时间会增加。 SELECT 中的 OFFSET 子句指示跳过了多少行。随着它变大,会选择并跳过更多行。

您需要将 SELECT 修改为:

SELECT ID, NAME, VALUE FROM MY_TABLE WHERE ID > ? ORDER BY ID FETCH ? ROWS ONLY

您可以像这样处理结果,使用正在运行的lastID和PreparedStatement。

long lastID = -1;

// repeat the rest of the code until the result is empty
selectStatement.setLong(1, lastID);
selectStatement.setInt(2, 100000);

ResultSet result = selectStatement.executeQuery();
while (result.next()) {
 Long id = result.getLong(1);
 lastID = id;
 // do stuff ...
}

关于java - 选择 HSQLDB 中 100 多百万行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47032173/

相关文章:

java - Maven - 将代码移动到新的 Artifact ;传递依赖问题

php - 如果使用准备好的 PHP/MySQL 查询,我是否需要清理输入?

java.lang.ClassNotFoundException : sun. jdbc.odbc.JdbcOdbcDriver 发生异常。为什么?

azure - 与使用JDBC从SQL Server读取表相比,使用SparkSQL访问Hive表有什么特别的好处?

Oracle 存储过程 java.sql.SQLException : Invalid column type: 2012 (REF_CURSOR)

postgresql - JDBC 似乎在我的数字周围加上单引号

java - 将参数传递给方法时,强化将查询标记为 sqlInjection

java - 自定义 Java 对话框颜色、外观、主题

Java 泛型,在 C<T extends MyClass<Z>> 中,方法应返回 Z

java - java应用程序中无法包含vlc库