更新sqlite3索引的时间波动太大

时间:2013-03-24 19:41:08

标签: performance sqlite

我有一个大型的sqlite3(3.6.22)数据库(大约1 GB,500万行),在一列上有一个索引的表。问题是进行典型INSERT事务的时间波动很大。我一次插入大约10000行(当然包装在事务中)。通常需要大约1.5秒,但是大约每五个交易一次,完成相同的交易突然需要几分钟。我已经做了很多实验,并且我发现这种现象只有在有索引时才会出现,这让我觉得它正在更新索引需要花费很多时间。

我需要更稳定的表现。如果我只能避免某些交易突然占用前一次的200倍,那么平均插入次数会更高一些......我该怎么办?

这是架构。 blocks.md5中的字符串总是长度为32个字节,可能是唯一的。 rolling.value列将包含非常大的64位整数。

CREATE TABLE blocks (blob char(32) NOT NULL, 
                     offset long NOT NULL, 
                     md5 char(32) NOT NULL, 
                     row_md5 char(32));
CREATE TABLE rolling (value INT NOT NULL);

CREATE INDEX index_md5 ON blocks (md5);
CREATE UNIQUE INDEX index_rolling ON rolling (value);

1 个答案:

答案 0 :(得分:1)

我不知道sqlite索引是如何实现的,但是如果他们将索引存储在磁盘上或重新排序数据,我会期待你所描述的行为。

想象一下这样一种场景:当他们为索引分配块时,他们会启动一些带有N个数据插槽的页面。当页面填满时,他们必须分配另一个并在它们之间拆分数据。

当您插入数据时,MD5的顺序将随机变化,因此每个页面都会独立填充。索引策略没有任何合理的方法来了解它。

其他数据库甚至建议对字符串使用不同于正常的索引策略,尤其是在随机MD5之类的情况下。

尝试在所有内存数据库中执行此操作将告诉您其算法或磁盘访问。

我只是试图在离线系统中避免这种情况,我可以在插入之前对数据进行排序。在它全部插入后,我会索引它,这是我能找到的速度。如果你一次做10k,这可能是你的用例,虽然我不知道。