【问题标题】:SQLite in write very slowSQLite 写入速度很慢
【发布时间】:2014-07-07 20:01:18
【问题描述】:

我研究过 sqlite,只是想问一下: 一个简单数据库中素数文件中一列的速度记录是 4 秒。可以吗,还是我有一些软件/硬件问题? 256 条笔记在 SQLite 中写入超过 4 秒和(非 mysql 文件写入为 2 毫秒) 我简直不敢相信 sqlite 写得这么慢。

我的比较 sqlite db work 和 file db work 的代码:

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);
}
}

结果:

run:
[07:53:49.829][DEBUG]: Start DB!
[07:53:53.223][DEBUG]: Done! (256)
[07:53:53.223][DEBUG]: Start File!
[07:53:53.253][DEBUG]: Done! (256)
BUILD SUCCESSFUL (total time: 5 seconds)

4 秒!哇!这很棒! 请告诉我 - 这是正常的还是我做错了什么?

已更新。

似乎,自动提交的问题。正如我刚才在某处读到的那样,“默认情况下,每个 INSERT 语句都是它自己的事务。但是如果你用 BEGIN...COMMIT 包围多个 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);
}
}

结果:

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)

感谢大家的回答!但是如果您对此有一些考虑,请,欢迎

【问题讨论】:

  • 你的代码有一些语法错误,仅供参考。
  • 请问?它对我有用,我现在就在 netbeans ide 中制作它
  • 哎呀,对不起,我看到了错误
  • 4 秒考虑数据库创建和驱动程序实例化和表创建
  • 您的代码使用SQLite,这与MySQL不同。

标签: java database performance sqlite optimization


【解决方案1】:

我可能会尝试不同的驱动程序。试试 mySQL 自带的那个: http://www.mysql.com/products/connector/

在 MySQL Connector/J 中实现 java.sql.Driver 的类名为 com.mysql.jdbc.Driver。

【讨论】:

  • Mike,对不起,我混淆了数据库的名称,我们在谈论 sqlite,但无论如何,谢谢你的回答!
  • 这是 sqlite,对不起,sqlite 呢?我看不到另一个 sqlite 驱动程序,仅限 JDBC
  • 不熟悉那个数据库,抱歉。也许你应该试试 MySQL :)
  • 似乎,我已经找到了解决方案,并且似乎是自动提交。谢谢)我更新线程
  • mysql 是很棒的数据库,但它需要一些其他的东西 - sqlite 的优雅之处在于它不需要单独的数据库服务器,它是大多数非大型应用程序所需要的
猜你喜欢
  • 2016-08-21
  • 2013-05-11
  • 2012-03-14
  • 2013-04-20
  • 1970-01-01
  • 1970-01-01
  • 2017-01-07
  • 1970-01-01
相关资源
最近更新 更多