【问题标题】:SQLite UPDATE 100msSQLite 更新 100 毫秒
【发布时间】:2012-10-30 16:25:00
【问题描述】:

我正在使用Qt database abstraction 层与 Sqlite3 进行交互。

int x = GetTickCount();
database.exec("UPDATE controls SET dtype=32 WHERE id=2");
qDebug() << GetTickCount()-x;

表格是:

CREATE TABLE controls (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    internal_id TEXT,
    name TEXT COLLATE NOCASE,
    config TEXT,
    dtype INTEGER,
    dconfig TEXT,
    val TEXT,
    device_id INTEGER REFERENCES devices(id) ON DELETE CASCADE
); 

更新时间约为 100 毫秒!即使没有其他东西正在访问数据库,并且该表中总共有 3 条记录。

这对我来说似乎太长了。 10 条记录已经需要一秒钟才能完成。这是我应该从 sqlite 获得的性能,还是让我在某个地方搞砸了? SELECT 查询足够快~1ms。


编辑 1

所以它不是 Qt。

sqlite3 *db;
if ( sqlite3_open("example.db",&db ) != SQLITE_OK )
{
    qDebug() << "Could not open";
    return;
}

int x = GetTickCount();
sqlite3_exec(db, "UPDATE controls SET dtype=3 WHERE id=2",0,0,0);
qDebug() << "Took" << GetTickCount() - x;

sqlite3_close(db);

这家伙花费的时间是一样的。

【问题讨论】:

  • 你在使用事务吗?尝试使用database.transaction(), database.exec('update here'), database.commit()。有时,如果您有任何未提交的更新语句挂起,这会减慢插入/更新速度

标签: c++ sql qt sqlite


【解决方案1】:

访问硬盘可能需要很长时间。

尝试以下方法之一:

PRAGMA journal_mode = memory;
PRAGMA synchronous = off;

所以它不会立即接触磁盘。

如果使用得当,SQLite 可以非常非常快。小型数据库的 select 语句是从缓存中回答的。

还有其他方法可以调整您的数据库。查看其他类似的问题: Improve INSERT-per-second performance of SQLite?

【讨论】:

  • 太棒了。只需添加 synchronous = off 即可减少 GetTickCount 无法测量的时间!!
  • synchronous = off 表示在 UPDATE/INSERT 期间发生断电的情况下,您很有可能会丢弃数据库。
  • 看起来很像,但性能确实需要。发生灾难性故障的可能性很小。我要做的是在初始化之前存储数据库的副本。如果 init 成功,这将是下一次启动的后备。由于这不是银行应用程序,并且可以从环境中重新创建数据(尽管速度很慢),这应该没问题。