【发布时间】:2011-11-24 11:23:54
【问题描述】:
我在运行 Linux 的 ARM 嵌入式平台上有一个 sqlite 数据库,但资源有限。存储设备是 microSD 卡。 Sqlite 版本是 3.7.7.1。访问 sqlite 的应用程序是用 C++ 编写的。
我想定期知道几个表中的行数。我目前使用
select count(*) from TABLENAME;
获取此信息。我遇到了性能问题:当表大小达到某个点(~200K 行)时,每次检查表大小时都会有很多系统和 iowait 负载。
当我写这篇文章时,我虽然查找表中的行数会很快,因为它可能存储在某个地方。但是现在我怀疑 sqlite 实际上会查看所有行,当我通过数据不再适合磁盘缓存的点时,我会得到很多 io 负载。这将大致适合 db 大小和可用内存。
谁能告诉我 sqlite 是否以我怀疑的方式行事?
有没有什么方法可以在不产生这么多负载的情况下获取表行数?
编辑:plaes 询问了表格布局:
CREATE TABLE %s (timestamp INTEGER PRIMARY KEY, offset INTEGER, value NUMERIC);
【问题讨论】:
-
可能这不是非常有效,但您可以通过添加触发器来修改您的数据库,这些触发器为每个表增加/减少一个全局行计数器。见sqlite.org/lang_createtrigger.html。
-
如果添加自增整数索引会发生什么?
-
@plaes:我查看了各种查询计划。计数查询似乎想要查看所有行(0|0|0|SCAN TABLE channel_17(~232666 行))。当我使用自动增量 rowid 创建一个测试表时,这仍然是正确的。 Sqlite Doku 说:“[...] PRIMARY KEY 约束是通过在数据库中创建索引来实现的”,因此缺少索引应该不是问题。
-
您能否对下表进行相同的“分析”:
CREATE TABLE %s (id INTEGER PRIMARY KEY AUTOINCREMENT, timestamp INTEGER, offset INTEGER, value NUMERIC);? (将插入NULL插入id列时) -
@plaes:我是为
CREATE TABLE %s (rowid INTEGER PRIMARY KEY AUTOINCREMENT, timestamp INTEGER UNIQUE, offset INTEGER, value NUMERIC);做的,这与以前的问题相同。
标签: linux performance sqlite