读了很多东西,比如这里: SQLite queries much slower using JDBC than in Firefox SqliteManager plugin
但我不知道问题是什么。 案例是,我有一个SQLite数据库(来自Android平板电脑)和一个不太大的表(约50.000行) 如果我运行"从表中选择* "例如在Sqlite Manager中它需要0.11秒,正确。
但是......如果我在Java程序(使用SQLite JDBC)中执行它需要20分钟!开个玩笑。
有人(某处)说这取决于版本。 但我的问题是如何?
因为这个命令:" SELECT sqlite_version()"在每种情况下,在同一个.db文件中给出不同的结果:
我可以整天更换JDBC驱动程序(我做了几次),但我怎么知道我需要哪个?
任何有想法的人?我完全坚持了它。
编辑: 好的,所以JDBC jar来自这里:https://bitbucket.org/xerial/sqlite-jdbc/downloads/
我的代码非常基本,起初我只想测量速度。
Class.forName("org.sqlite.JDBC");
Connection c1 = DriverManager.getConnection("jdbc:sqlite:" + "c:\\database.db");
PreparedStatement stmt1 = c1.prepareStatement("select * from table1;");
ResultSet rs = stmt1.executeQuery();
String script = "insert into table1 values ";
while (rs.next()) {
script += "(";
script += rs.getInt(1) + ", '" + rs.getString(2) + "', '" + rs.getString(3) + "'";
script += "),";
}
stmt1.close();
c1.close();
executeQuery()行需要20分钟。
答案 0 :(得分:0)
您正在创建一个包含50k行的String
,这意味着您正在创建 50k * 5 String
(每个连接都会创建一个新的String
实例。什么会杀死你的表现。
while (rs.next()) {
script += "(";
script += rs.getInt(1) + ", '" + rs.getString(2) + "', '" + rs.getString(3) + "'";
script += "),";
}
我注意到您没有执行String script
,因此如果您只想创建String
,请使用StringBuilder
StringBuilder script = new StringBuilder("insert into table1 values ");
while (rs.next()) {
script.append("(")
.append(rs.getInt(1)).append(", '")
.append(rs.getString(2)).append("', '")
.append(rs.getString(3)).append("'")
.append("),");
}
script.setLength(script.length() - 1); //to remove the last comma.
String query = script.toString();
StringBuilder
阻止为无创建的大量String
实例。
如果您想在此之后插入这些值,请直接使用PreparedStatement
而不是构建查询:
PreparedStatement psInsert = c1.prepareStatement("insert into table1 values (?,?,?)");
while (rs.next()) {
psInsert.setInt(1, rs.getInt(1));
psInsert.setString(2, rs.getString(2));
psInsert.setString(2,rs.getString(3));
psInsert.execute();
}
然后,如果要改进这一点,请使用批处理系统发送小块插入。使用Statement.addBatch()
和Statement.executeBatch()
while (rs.next()) {
psInsert.setInt(1, rs.getInt(1));
psInsert.setString(2, rs.getString(2));
psInsert.setString(2,rs.getString(3));
psInsert.addBatch();
if(batchSize++ > 100){ //Execute every 100 rows
psInsert.executeBatch();
batchSize = 0;
}
}
if(batchSize > 0){ //execute the remainings data
psInsert.executeBatch();
}
不是官方的,只是简单执行的持续时间
LocalTime start = LocalTime.now();
StringBuilder sb = new StringBuilder("Foo;");
for(int i = 0; i < 50_000; i++){
sb.append("Row").append(i).append(";\n");
}
System.out.println(Duration.between(start, LocalTime.now()).toNanos());
String s = sb.toString();
System.out.println(s.substring(0, 50));
这需要15纳秒
LocalTime start = LocalTime.now();
String s = "Foo;";
for(int i = 0; i < 50_000; i++){
s += "Row" + i + ";\n";
}
System.out.println(Duration.between(start, LocalTime.now()).toMillis());
System.out.println(s.substring(0, 50));
这需要> 6秒