我在Java中创建一个使用SQLite存储和搜索数据库中数据的应用程序。
我不确定我是否会以最有效的方式解决这个问题而且我认为有人可以帮我解决这个问题。
背景信息:我的Java应用程序使用可以将PDF文件中的原始文本转换为StringWriter的库来解析.PDF文件。然后我解析结果数据并获取在数据库中创建一些新行所需的信息。但是,生成的表非常大,因为要解析大约900个PDF文件。只是为了让你知道我说的有多大,其中一个表最后有大约145000行,另一个有1550行,其他(3或4个其他表)有75到750行。
一切正常,但我不确定是否可以降低创建表格所需的时间。到目前为止,在我的笔记本电脑上,第一次创建所有内容需要41分钟(尽管所有内容都来自USB闪存盘...我稍后会在硬盘上测试它)。我再次运行它需要1.5分钟,因为它检查文件是否已经被解析并且它不会重新创建所有内容。我不需要它是一个巨大的改进,因为理想情况下我每周只运行一次大约30个文件,但是,我仍然想知道为什么它有900个文件这么慢;如果它是解析文件的代码很慢,或者在SQLite部分我的结尾是不好的做法。 (我正在使用去年创建的所有文件对其进行测试,这就是我有这么多文件的原因)
那么,使用SQLite在Java中提高性能的最佳实践是什么?将autocommit置于false并仅在创建所有内容后提交会产生明显的区别吗?有没有办法创建语句或测试数据是否已经以更有效的方式存在?
我没有我的代码,但查询看起来有点像这样:
public static void insertScores(String league, int playerID, int score, String date)
{
PreparedStatement ps = new PreparedStatement("INSERT INTO Scores(?,?,?,?)");
ps.setString(1, league);
[...]
ps.executeUpdate();
}
在其他查询中,我使用类似的东西测试该行是否已存在:
public static void insertScores(int playerID)
{
ResultSet rs = null;
PreparedStatement ps = new PreparedStatement("SELECT * FROM Scores WHERE ID = ?");
ps.setInt(1, playerID);
rs = ps.executeQuery();
if(!rs.next())
{
[code like in the first example]
}
}
请记住,语法错误是因为我只是在心里打字,因为我没有我的代码。
仅仅通过查看这些示例并阅读我要说的内容,是否有人知道如何提高SQL语句的性能?
答案 0 :(得分:2)
两个建议:
1)获取一个分析器。您可以猜测是什么让您的代码变慢,或者您可以对其进行分析并知道是什么导致代码变慢。
2)由于您的数据位于慢速设备上,因此您希望尽可能少地进行读/写。 SELECT *
带回整行,但是你只需检查是否存在。试试SELECT ID
,只需要阅读一个数字。
答案 1 :(得分:1)
Scores中有多少条记录具有相同的playerID?如果它足够多,请尝试确定特定播放器ID的存在:
select 1 where exists(select 1 from scores where id = ?)
或类似的。我不熟悉SQLite中使用的SQL方言,但这种方法通常有助于在找到具有指定playerID的第一条记录时对进一步的计算进行短路。
答案 2 :(得分:0)
当您进行大量小更新时,USB闪存驱动器的性能会非常糟糕。 Flash需要read an entire block into a buffer, update its relevant part, erase the block and then write back the buffer。 (SSD有一些逻辑可以缓解这种情况。)
将您的数据移至硬盘并查看是否有帮助。