如何计算 sqlite3 写入容量

How sqlite3 write capacity is calculated

提问人:Karim 提问时间:4/15/2018 最后编辑:Karim 更新时间:4/15/2018 访问量:100

问:

我创建测试表

create table if  not exists `HKDevice` (primaryID integer PRIMARY KEY AUTOINCREMENT,mac integer)

插入 1 行:

NSString *sql = @"insert into `HKDevice` (mac)values('0')";
int result = sqlite3_exec(_db, sql.UTF8String, NULL, NULL, &errorMesg);

磁盘报告写入 48KB
enter image description here

这比我想象的要大得多,我知道 sqlite 中的整数大小为 4 字节,我认为应该写总量小于 10 字节。
第二次写也接近第一次的大小,所以我比较困惑...... 有人能告诉我为什么吗?谢谢!

iOS iPhone SQLite

评论


答:

0赞 mhawke 4/15/2018 #1

将涉及一些元数据开销。首先,将创建数据库文件,该文件必须维护表、索引、序列、自定义函数等的模式。这些都会影响磁盘空间的使用。

例如,在 Linux 上,将上面定义的数据库表添加到新数据库将生成大小为 12288 字节 (12KB) 的文件。如果表更多,空间需求将增加,就像向表添加数据时一样。

此外,出于效率原因,数据库通常以“页”的形式将数据写入磁盘,即分配一页(或块)空间,然后写入其中。将选择页面大小以优化 I/O,例如 4096 字节。因此,如果需要新页面,写入单个整数可能需要 4KB 的磁盘。但是,您会注意到,写入第二个整数不会占用更多空间,因为现有页面中有足够的可用空间。页面已满后,将分配一个新页面,并且磁盘大小可能会增加。

以上是有点简化。数据库页面分配和管理策略是一个复杂的主题。我敢肯定,搜索会找到许多包含SQLite详细信息的资源。

评论

0赞 Karim 4/15/2018
实际上,第二次写入的大小也接近第一次的大小,所以我比较困惑......
0赞 mhawke 4/15/2018
这不是我所经历的。需要将 527 个相同的提交插入到该表中才能更改文件大小。它高度依赖于数据库引擎的调优,这无疑会因操作系统和环境而异。如果您的 DB 文件每次写入都会增加 48K 字节,那么我会担心。你是说这就是正在发生的事情吗?
0赞 Karim 4/15/2018
在我的项目中,有时需要在表中插入或更新超过 200~500 行,写入速率 5~10MB/s 太快会使 UI 队列阻塞一秒钟。我想更多地了解sqlite写做事
0赞 mhawke 4/15/2018
看来我误解了你的问题。您谈论的是数据传输,而不是磁盘空间使用情况。我认为@CL的答案更好地解决了这个问题。
1赞 CL. 4/15/2018 #2

对于较大的操作,将每一行单独写入文件效率低下,因此数据库始终读取和写入整个页面。

INSERT 命令至少需要修改三页:表数据、包含 AUTOINCREMENT 计数器的系统表和数据库头中的数据库更改计数器。

为了使更改即使在中断的情况下也能实现原子化,数据库需要将所有已更改页面的旧数据保存在回滚日志中。总共有六页。

如果不对这两个命令使用显式事务,则每个命令都会自动包装到自动事务中,因此您可以同时获得这两个命令的这些写入。总共有十二页。

默认页面大小为 4 KB,这是您看到的写入量。 (显然,文件系统元数据的写入不会显示在报告中。