所以我尝试将 SQLite 与相当基本的 SQL 查询一起使用(对于那些不熟悉 GLOB 的人,它类似于 LIKE):
SELECT * FROM dictionary where word GLOB '[paple][paple][paple][paple][paple]';
我可以在 SQLite 管理器中运行它,检索所有记录大约需要 50 毫秒。现在我用 Java 编写了以下代码,它花费了将近 1.5 秒,相比之下这似乎慢得离谱。我知道这可能需要更长的时间,但 1450 毫秒的速度慢得令人无法接受:
Connection conn = DriverManager.getConnection("jdbc:sqlite:dictionary.sqlite");
Statement stat = conn.createStatement();
long start = System.currentTimeMillis();
ResultSet rs = stat.executeQuery("SELECT * FROM dictionary where word GLOB '[paple][paple][paple][paple][paple]';");
while (rs.next()) {
System.out.println("word = " + rs.getString("word"));
}
rs.close();
conn.close();
long end = System.currentTimeMillis();
System.out.println("Took: " + (end - start));
我有一种感觉,每次调用 ResultSet.next() 时它都必须重新查询数据库,因为它不会立即获取所有记录,但我不是 100% 确定。我觉得应该有一种更有效的方法来做到这一点。所以我的问题是有没有人知道如何改进 Java 代码以使其更快?
PS:我用的是sqliteJDBC .这里的实现会减慢我的速度吗?只是我的一个想法。
最佳答案
每次调用ResultSet#getString(String)
,你强制完成很多工作。参见 the JDBC driver its internal method RS#findColumn(String)
的代码.请注意,它不会缓存列名到列序号索引的映射。对于您检查的结果集中的每一行,您都要进行多次字符串比较和大小写转换操作。
尝试将您对 ResultSet#getString(String)
的使用替换为 ResultSet#getString(int)
.首先,在 while
循环之外的早期,找出您希望提取的列的索引。 (请注意,用显式列列表替换 SELECT *
会好得多,在这种情况下,您已经知道每列的序号索引。)
final int indexWord = rs.findColumn("word");
然后,在迭代期间,使用先前确定的索引:
// Avoid concatenating:
System.out.print("word = ");
System.out.println(rs.getString(indexWord));
让我们知道该优化是否会产生显着影响。
关于java - SQLite 查询在 Java 中非常慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8623551/