Java中的SQLite:优化我的查询以使其返回更快的方法?

Java中的SQLite:优化我的查询以使其返回更快的方法?,java,sqlite,Java,Sqlite,我正在用Java创建一个应用程序,它使用SQLite在数据库中存储和搜索数据 我不确定我是否以最有效的方式处理这个问题,我想这里有人可以帮我解决这个问题 背景信息:我的Java应用程序使用一个库解析.PDF文件,该库可以将PDF文件中的原始文本转换为StringWriter。然后,我解析结果数据并获取在数据库中创建新行所需的信息。不过,生成的表非常大,因为大约有900个PDF文件需要解析。为了让您了解我所说的有多大,其中一个表的行数大约为145000行,另一个表的行数为1550行,其他表(3或4

我正在用Java创建一个应用程序,它使用SQLite在数据库中存储和搜索数据

我不确定我是否以最有效的方式处理这个问题,我想这里有人可以帮我解决这个问题

背景信息:我的Java应用程序使用一个库解析.PDF文件,该库可以将PDF文件中的原始文本转换为StringWriter。然后,我解析结果数据并获取在数据库中创建新行所需的信息。不过,生成的表非常大,因为大约有900个PDF文件需要解析。为了让您了解我所说的有多大,其中一个表的行数大约为145000行,另一个表的行数为1550行,其他表(3或4个其他表)的行数介于75到750行之间

一切正常,但我不确定我是否能缩短创建表和其他内容所需的时间。到目前为止,在我的笔记本电脑上,第一次创建所有内容需要41分钟(尽管所有内容都是从USB闪存驱动器运行的……我稍后会在HDD上进行测试)。我再次运行它需要1.5分钟,因为它会检查文件是否已被解析,并且不会重新创建所有内容。我不需要它是一个巨大的改进,因为理想情况下,我每周只运行一次这个程序,大约有30个文件,但我仍然想知道为什么它有900个文件,速度这么慢;如果是解析文件的代码太慢,或者是我在SQLite部分的错误做法。(我正在用去年创建的所有文件测试它,这就是为什么我有那么多文件的原因)

那么,在Java中使用SQLite提高性能的最佳实践是什么?将“自动提交”设置为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]
  }
}
在其他查询中,我使用以下方法测试行是否已经存在:

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语句的性能吗?

两条建议:

1) 找一个剖析器。你可以猜测是什么使你的代码变慢,或者你可以简单地分析它,知道是什么使它变慢

2) 由于数据位于速度较慢的设备上,因此您希望尽可能少地读/写数据
SELECT*
返回整行,然后检查是否存在。尝试
选择ID
,它只需要读取一个数字。

两条建议:

1) 找一个剖析器。你可以猜测是什么使你的代码变慢,或者你可以简单地分析它,知道是什么使它变慢


2) 由于数据位于速度较慢的设备上,因此您希望尽可能少地读/写数据
SELECT*
返回整行,然后检查是否存在。尝试
选择ID
,它只需要读取一个数字。

分数中有多少记录具有相同的playerID?如果足够,尝试确定特定玩家ID的存在,例如:

select 1 where exists(select 1 from scores where id = ?)

或类似的。我不熟悉SQLite中使用的SQL方言,但这种方法通常有助于在找到具有指定playerID的第一条记录时简化进一步的计算。

分数中有多少条记录具有相同的playerID?如果足够,尝试确定特定玩家ID的存在,例如:

select 1 where exists(select 1 from scores where id = ?)

或类似的。我不熟悉SQLite中使用的SQL方言,但这种方法通常有助于在找到具有指定playerID的第一条记录时简化进一步的计算。

在进行大量小更新时,USB闪存驱动器的性能很差。Flash需要升级。(SSD有逻辑来缓解这一点。)


将数据移动到硬盘上,看看是否有帮助。

当您进行大量小更新时,USB闪存驱动器的性能会很差。Flash需要升级。(SSD有逻辑来缓解这一点。)


将您的数据移动到硬盘,看看是否有帮助。

@9000我为表中的多个列设置了主键,这算不算,还是我真的必须为搜索的给定列使用特定索引?您似乎认为是应用程序的SQL部分导致了问题-我首先配置并检查,否则,您可能会花很多时间试图改进错误部件的性能@9000我为我的表中的多个列设置了一个主键,这算不算,还是我真的必须为我搜索的给定列使用特定索引?您似乎认为是应用程序的SQL部分导致了问题-我首先配置并检查,否则,您可能会花很多时间试图改进错误部件的性能!这对于第2点来说非常有意义,我将更改它并测试它。至于探查器,我不熟悉这个概念。你知道我应该在哪里找到一个运行良好的工具吗?谷歌搜索“java profiler”。我们在工作中使用JProfiler。这是一个开源的列表,对于第2点来说非常有意义,我会修改它并测试它。至于探查器,我不熟悉这个概念。你知道我应该在哪里找到一个运行良好的工具吗?谷歌搜索“java profiler”。我们在工作中使用JProfiler。这是一个开源的列表,在阅读了你的文章之后,我查找了exists的语法,因为我只知道exists的语法,比如create if not exists或drop if exists等等。我不知道你可以传递另一个查询来查看它是否返回了什么。我认为这将是我的表现提高最多的地方。谢谢我刚测试过,效果很好。在相同的文件上运行代码时,我只得到了大约45%的改进。非常感谢你!之后