【发布时间】:2014-09-20 10:46:37
【问题描述】:
我想在不使用限制子句的情况下从数据库中获取一些记录(它可以是 50,100 或用户配置的其他内容),因为我们的应用程序可能在多个数据库上工作,例如 mysql、oracle、mssql、db2....
我做了以下解决方案
package com.test;
import java.sql.Connection;
import java.sql.Statement;
import java.sql.ResultSet;
import java.sql.DriverManager;
import java.util.Date;
public class BatchRetrieveTest extends Object {
private static final int FETCH_SIZE = 10;
public BatchRetrieveTest() {
}
public static void main(String[] args) {
BatchRetrieveTest batchRetrieveTest = new BatchRetrieveTest();
batchRetrieveTest.test();
}
void test() {
Connection conn = null;
Statement stmt2 = null;
Date start = null;
Date end = null;
int i = 0;
try {
conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/test",
"root", "root");
stmt2 = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_READ_ONLY);
conn.setAutoCommit(false);
stmt2.setFetchSize(FETCH_SIZE);
stmt2.setPoolable(true);
start = new Date();
System.out.println(new Date() + "second execute start"
+ new Date().getTime());
ResultSet rs2 = stmt2
.executeQuery("SELECT * FROM sample_final_attendance limit 1000");
end = new Date();
System.out.println(new Date() + "*************second execute end"
+ (end.getTime() - start.getTime()));
rs2.absolute(200000);
i = 0;
while (rs2.next()) {
if (i++ > 100) {
break;
}
}
rs2.close();
stmt2.close();
end = new Date();
System.out.println(new Date() + "second read end"
+ (end.getTime() - start.getTime()));
conn.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
stmt2.close();
conn.close();
} catch (Exception e) {
}
}
}
}
这里 sample_final_attendance 表包含 15 列和 320 万条记录 执行此程序时需要 2GB 内存和 47 秒的执行时间
我想知道如果某个表有数十亿条记录,那么它会执行失败
我也按照建议使用了setFetchSize,但问题是一样的
请提出一些解决方案
提前致谢
【问题讨论】:
-
@Scary Wombat 没错,但这在其他数据库中不起作用我想要适用于所有数据库的通用解决方案
-
这段代码是如何工作的? SQL 语句的
LIMIT子句说让我获得前 1000 行,然后移动到结果集的第 200,000 行。我原以为你最终会得到rs2.next()返回false,而while循环什么也不做。我错过了什么? -
我使用了 ResultSet.TYPE_SCROLL_SENSITIVE 所以你可以向前移动到你想要移动的记录
-
但是您有一个最多包含 1000 行的结果集,并且您移动到第 200,000 行 - 这将如何工作?
-
我将 fetchsize 设置为 1000 而不是 maxfetchsize 所以它可以工作