2020年更新,大约11年前这个问题被发布,后来被关闭,阻止了更新的答案。

这里写的几乎都过时了。曾几何时,sqlite被限制在内存容量或2gb的存储空间(32位)或其他流行的数字…那是很久以前的事了。

官方限制列在这里。实际上,只要有可用的存储空间,sqlite就可能工作。它适用于比内存大的数据集,它最初是在内存很薄的时候创建的,从一开始就非常重要。

存储100gb的数据绝对没有问题。它可能可以很好地存储TB,但最终这是你需要质疑SQLite是否是最好的工具,你可能想要一个完整的数据库的功能(远程客户端,并发写入,只读副本,分片等…)


原:

我知道即使sqlite支持超大的数据库文件,sqlite也不能很好地处理它们(sqlite网站上曾经有一条评论说,如果你需要超过1GB的文件大小,你可能要考虑使用企业rdbms。再也找不到它了,可能与sqlite的旧版本有关)。

然而,出于我的目的,我想在考虑其他解决方案之前了解它到底有多糟糕。

我说的是从2GB开始的千兆字节范围的sqlite数据文件。 有人有这方面的经验吗?任何建议/想法吗?


当前回答

>花费48小时进行插入的主要原因是您的索引。它是令人难以置信的快:

1 -删除所有索引 2 -做所有的插入 3 -重新创建索引

其他回答

因此,我使用sqlite对非常大的文件进行了一些测试,并得出了一些结论(至少对于我的特定应用程序)。

测试涉及单个sqlite文件,其中包含单个表或多个表。每个表大约有8列,几乎都是整数,还有4个索引。

我们的想法是插入足够的数据,直到sqlite文件达到50GB左右。

单表

我尝试将多行插入到只有一个表的sqlite文件中。当文件大约7GB时(对不起,我不能具体说明行数),插入花费的时间太长了。我曾估计插入所有数据的测试需要24小时左右,但即使在48小时后也没有完成。

这使我得出结论,一个非常大的sqlite表在插入和其他操作方面都会有问题。

我想这并不奇怪,随着表变大,插入和更新所有索引需要更长的时间。

多个表

然后,我尝试将数据按时间分割到几个表中,每天一个表。原始1个表的数据被分割为~700个表。

这种设置没有插入问题,随着时间的推移,它不会花费更长的时间,因为每天都会创建一个新表。

真空问题

正如i_like_caffeine所指出的,sqlite文件越大,VACUUM命令就会产生问题。随着插入/删除操作的增加,磁盘上文件的碎片会变得更糟,因此目标是定期使用VACUUM来优化文件并恢复文件空间。

然而,正如文档所指出的,数据库的完整副本是做真空的,需要很长时间才能完成。因此,数据库越小,该操作完成的速度就越快。

结论

对于我的特定应用程序,我可能会将数据分割到几个db文件中,每天一个,以获得最佳的真空性能和插入/删除速度。

这使查询变得复杂,但对我来说,能够索引这么多数据是值得的。另一个优点是,我可以删除整个db文件来删除一天的数据(这是我的应用程序的常见操作)。

我可能还要监视每个文件的表大小,以查看速度何时会成为问题。

除了自动真空,似乎没有增量真空方法,这太糟糕了。我不能使用它,因为我对真空的目标是整理文件(文件空间不是大问题),这是自动真空做不到的。事实上,文档表明这可能会使碎片化更糟,所以我必须定期对文件进行完全真空处理。

>花费48小时进行插入的主要原因是您的索引。它是令人难以置信的快:

1 -删除所有索引 2 -做所有的插入 3 -重新创建索引

我创建了最大3.5GB的SQLite数据库,没有明显的性能问题。如果我没记错的话,我认为SQLite2可能有一些下限,但我不认为SQLite3有任何这样的问题。

根据SQLite Limits页面,每个数据库页面的最大大小是32K。数据库中的最大页面是1024^3。根据我的计算,最大大小是32tb。我认为在达到SQLite的限制之前,您将达到您的文件系统的限制!

我认为关于sqlite缩放的主要抱怨是:

单进程写。 没有镜像。 没有复制。

我们在我们的平台上使用的是50gb以上的DBS。没有抱怨很有效。 确保你做的每件事都是正确的!您是否使用预定义语句? * SQLITE 3.7.3

交易 预先发表的声明 应用这些设置(在创建DB之后) 编译指示主要。Page_size = 4096; 编译指示main.cache_size = 10000; 编译指示main.locking_mode =独家; 编译指示main.synchronous =正常; 编译指示main.journal_mode =细胞膜; 编译指示main.cache_size = 5000;

希望这将帮助其他人,在这里工作得很好