Java SQLite的写入速度非常慢
我研究过sqlite,只想问: 在一个简单数据库中,一列素数文件中的速度记录为4秒。还好吗,还是我有一些软件/硬件问题? 256条注释在SQLite中写入时间超过4秒(非mysql文件写入时间为2毫秒) 我简直不敢相信sqlite写得这么慢 用于比较sqlite数据库工作和文件数据库工作的我的代码:Java SQLite的写入速度非常慢,java,database,performance,sqlite,optimization,Java,Database,Performance,Sqlite,Optimization,我研究过sqlite,只想问: 在一个简单数据库中,一列素数文件中的速度记录为4秒。还好吗,还是我有一些软件/硬件问题? 256条注释在SQLite中写入时间超过4秒(非mysql文件写入时间为2毫秒) 我简直不敢相信sqlite写得这么慢 用于比较sqlite数据库工作和文件数据库工作的我的代码: package demo_SQLite; import java.io.BufferedOutputStream; import java.io.DataOutputStream; import
package demo_SQLite;
import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
public class demo_SQLite {
private static Connection conn;
private static Statement state;
private static File db = new File("datafile");
public static void main(String[] args) throws IOException {
Debug("Start DB!");
run();
}
private static void run() throws IOException {
try {
if (!db.exists()) {
db.createNewFile();
}
Class.forName("org.sqlite.JDBC");
conn = DriverManager.getConnection("jdbc:sqlite:" + db);
state = conn.createStatement();
state.executeUpdate("create table if not exists a(id integer,"
+ "time INT,"
+ "primary key (id));");
PreparedStatement prep = conn.prepareStatement("insert into a values(?,?)");
for (int i = 0; i < 257; i++) {
int l = new Random().nextInt();
prep.setInt(2, l);
prep.execute();
}
prep.close();
state.close();
Debug("Done! (256)");
file();
} catch (Exception ex) {
Logger.getLogger(Demo_MySQL.class.getName()).log(Level.SEVERE, null, ex);
}
}
private static void file() {
try {
Debug("Start File!");
File file = new File("filebase");
DataOutputStream dos = null;
dos = new DataOutputStream
(new BufferedOutputStream(new FileOutputStream(file)));
int r = 0;
for (int i = 0; i < 257; ++i) {
r = new Random().nextInt();
dos.writeInt(r);
}
dos.flush();
dos.close();
Debug("Done! (256)");
} catch (IOException ex) {
Logger.getLogger(Demo_MySQL.class.getName()).log(Level.SEVERE, null, ex);
}
}
public static void Debug(String msg) {
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss.SSS");
Date date = new Date();
System.out.println("[" + sdf.format(date) + "][DEBUG]: " + msg);
}
}
4秒!哇!太棒了!
请告诉我-这是正常的还是我做错了什么
更新
似乎是自动提交的问题。我刚才在什么地方读到,默认情况下,每个INSERT语句都是自己的事务。但是如果用BEGIN…COMMIT包围多个INSERT语句,那么所有的INSERT都被分组到一个事务中。提交事务所需的时间将分摊到所有随附的insert语句中,因此每个insert语句的时间将大大减少。”
我刚刚禁用了自动提交-
更正代码和新结果:
package demo_sqlite;
import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
public class demo_SQLite {
private static Connection conn;
private static Statement state;
private static File db = new File("datafile");
public static void main(String[] args) throws IOException {
Debug("Start DB!");
run();
}
private static void run() throws IOException {
try {
if (!db.exists()) {
db.createNewFile();
}
//run db driver
Class.forName("org.sqlite.JDBC");
conn = DriverManager.getConnection("jdbc:sqlite:" + db);
state = conn.createStatement();
//check table
state.executeUpdate("create table if not exists a(id integer,"
+ "time INT,"
+ "primary key (id));");
conn.setAutoCommit(false);
// clear table if table not clear
state.execute("DELETE FROM a");
conn.commit();
//make needed notes for db
PreparedStatement prep = conn.prepareStatement("insert into a values(?,?)");
for (int i = 0; i < 256; ++i) {
int l = new Random().nextInt();
prep.setInt(2, l);
prep.execute();
}
conn.commit();
prep.close();
//reading notes for chek
List<Integer> notes = new LinkedList<Integer>();
ResultSet res = state.executeQuery("select * from a");
while (res.next()) { int n = res.getInt("time"); notes.add(n); }
res.close();
state.close();
Debug("Done! ("+ notes.size() + ")");
//write to a file for comparing the write speed
Debug("Start File!");
File file = new File("filebase");
DataOutputStream dos = null;
dos = new DataOutputStream
(new BufferedOutputStream(new FileOutputStream(file)));
int r = 0;
for (int i = 0; i < 256; ++i) {
r = new Random().nextInt();
dos.writeInt(r);
}
dos.flush();
dos.close();
Debug("Done! (256)");
//done! see log for result
} catch (Exception ex) { }
}
public static void Debug(String msg) {
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss.SSS");
Date date = new Date();
System.out.println("[" + sdf.format(date) + "][DEBUG]: " + msg);
}
}
谢谢大家的回答!但是如果您对此有一些考虑,请欢迎我可能会尝试其他驱动程序。请尝试mySQL附带的驱动程序: 在MySQL Connector/J中实现java.sql.Driver的类的名称是com.MySQL.jdbc.Driver
您的代码有一些语法错误,仅供参考。打扰一下?这对我来说很有效,我现在在netbeans ide中制作。哎哟,对不起,考虑到数据库创建、驱动程序实例化和表创建,我看到了4秒的错误。您的代码使用
SQLite
,这与MySQL
不同。迈克,抱歉,我弄错了数据库的名称,我们是tal关于sqlite,但是无论如何,谢谢你的回答!这是sqlite,对不起,关于sqlite呢?我看不到sqlite的其他驱动程序,只有JDBC不熟悉那个数据库,对不起。也许你应该试试MySQL:)似乎,我已经找到了解决方案,似乎是自动提交。谢谢)我更新了threadmysql是一个很棒的数据库,但它需要一些其他的功能ings-sqlite的优雅之处在于它不需要单独的DB服务器,这是大多数非大型应用程序所需要的
package demo_sqlite;
import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
public class demo_SQLite {
private static Connection conn;
private static Statement state;
private static File db = new File("datafile");
public static void main(String[] args) throws IOException {
Debug("Start DB!");
run();
}
private static void run() throws IOException {
try {
if (!db.exists()) {
db.createNewFile();
}
//run db driver
Class.forName("org.sqlite.JDBC");
conn = DriverManager.getConnection("jdbc:sqlite:" + db);
state = conn.createStatement();
//check table
state.executeUpdate("create table if not exists a(id integer,"
+ "time INT,"
+ "primary key (id));");
conn.setAutoCommit(false);
// clear table if table not clear
state.execute("DELETE FROM a");
conn.commit();
//make needed notes for db
PreparedStatement prep = conn.prepareStatement("insert into a values(?,?)");
for (int i = 0; i < 256; ++i) {
int l = new Random().nextInt();
prep.setInt(2, l);
prep.execute();
}
conn.commit();
prep.close();
//reading notes for chek
List<Integer> notes = new LinkedList<Integer>();
ResultSet res = state.executeQuery("select * from a");
while (res.next()) { int n = res.getInt("time"); notes.add(n); }
res.close();
state.close();
Debug("Done! ("+ notes.size() + ")");
//write to a file for comparing the write speed
Debug("Start File!");
File file = new File("filebase");
DataOutputStream dos = null;
dos = new DataOutputStream
(new BufferedOutputStream(new FileOutputStream(file)));
int r = 0;
for (int i = 0; i < 256; ++i) {
r = new Random().nextInt();
dos.writeInt(r);
}
dos.flush();
dos.close();
Debug("Done! (256)");
//done! see log for result
} catch (Exception ex) { }
}
public static void Debug(String msg) {
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss.SSS");
Date date = new Date();
System.out.println("[" + sdf.format(date) + "][DEBUG]: " + msg);
}
}
run:
[09:01:36.890][DEBUG]: Start DB!
[09:01:37.052][DEBUG]: Done! (256)
[09:01:37.053][DEBUG]: Start File!
[09:01:37.054][DEBUG]: Done! (256)
BUILD SUCCESSFUL (total time: 0 seconds)