2014-02-05 31 views
1

我知道插入/更新多行时SQLite的'问题',但这不是这里的情况。SQLite更新一个记录是非常(相对)慢

我正在更新一行中的一个字段,由PK索引,在表中有〜250条记录。查询总是需要〜200毫秒。这听起来很少,但它很大。

为什么1很简单UPDATE查询需要200毫秒?所有的阅读都很快。

我已经试过:

  • BEGINCOMMIT - 没有变化,因为它只是1个语句
  • PRAGMA journal_mode=PERSIST - 没有变化,显然是磁盘IO是没有问题吗?
  • 去除UPDATE陈述 - 奇妙的作品的时间!但它不是很执着

比较到MySQL在同一系统上:0.6ms在一个非常类似的数据库。

我不需要交易安全(ACID?)或任何你称之为的东西。如果在查询过程中计算机崩溃,我很好,输了全部的变化。 MySQL(InnoDB)有一个选项:innodb_flush_log_at_trx_commit。 SQLite有类似的东西吗?

我正在使用sqlite-3.7.9,如果这很重要。

+0

您是否尝试过设置[VACUUM](http://www.sqlite.org/lang_vacuum.html)参数? – ldav1s

+0

'VACUUM'会重建数据库?但它是一个很小的分贝(270 kb)。更新的字段未编入索引。我将如何执行VACUUM,只是为了尝试? – Rudie

+0

我做了一个VACUUM,现在db文件稍小=)就是这样。没有下面的答案,它仍然是一个非常缓慢的'更新'。 – Rudie

回答

6

是,SQLite的有一个像MySQL的innodb_flush_log_at_trx_commit一个选项:

PRAGMA synchronous=OFF 

,它就像一个魅力。没有ACID,是速度。出于一些不可思议的原因,UPDATE现在需要< 1ms。

另外也提高了journal_mode

PRAGMA journal_mode=MEMORY 
or 
PRAGMA journal_mode=OFF 

两者都非常快,不耐酸。回滚不是问题,所以在这种情况下两者都很好。 OFF是最快的,因为它根本不创建日志(?)。

+1

使用'synchronous = OFF'或'journal_mode = OFF'时要小心,因为它可以[损坏数据库](https://sqlite.org/howtocorrupt.html)。 –

0

SQLite是处理轻量级数据集的好选择。是的,在插入/更新数据时,它比任何数据库要慢得多。可以通过自己提交查询来加速这些操作。请通过下面的演示代码。我已经用JDBCTemplate Spring框架引用了JAVA代码来执行我的数据库操作。请使用try-catch bolck处理所需的例外

conn = DataSourceUtils.getConnection(jdbcTemplate.getDataSource()); 
conn.setAutoCommit(false); 
PreparedStatement stmt = conn.prepareStatement(query_string); 
for(Object[] temp:argsListForInsertQuery) 
{ 
    stmt.setString(1, (String)temp[0]); 
    stmt.setString(2, (String)temp[1]); 
    stmt.setString(3, (String)temp[2]); 
    stmt.setString(4, (String)temp[3]); 
    stmt.addBatch(); 
} 
stmt.executeBatch(); 
conn.commit(); 
conn.setAutoCommit(true); 
conn.close(); 
+0

我知道一个。 SQLite网站谈论其插入速度与交易。尽管我的用例只有1个查询。或者几个无关的。 (不应该'conn'有一个类型?) – Rudie