1

我有一个大型 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);
4

1 回答 1

1

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

想象一个场景,当他们为索引分配块时,他们开始了一些带有 N 个数据槽的页面。当页面填满时,他们必须分配另一个页面并在它们之间拆分数据。

当您插入数据时,MD5 的顺序将尽可能随机,因此每个页面都会独立填满。索引策略没有任何合理的方法可以知道这一点。

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

尝试在全内存数据库中执行此操作会告诉您它是算法访问还是磁盘访问。

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

于 2013-03-28T05:34:42.737 回答