我知道sqlite即使支持超大数据库文件也不能很好地工作(在sqlite网站上曾经有评论说,如果您需要的文件大小超过1GB,则可能要考虑使用企业rdbms。找不到了,可能与旧版本的sqlite有关)。
但是,出于我的目的,我想在考虑其他解决方案之前先了解一下它的严重程度。
我说的是从2GB开始的数GB范围内的sqlite数据文件。有人对此有经验吗?有任何提示/想法吗?
我知道sqlite即使支持超大数据库文件也不能很好地工作(在sqlite网站上曾经有评论说,如果您需要的文件大小超过1GB,则可能要考虑使用企业rdbms。找不到了,可能与旧版本的sqlite有关)。
但是,出于我的目的,我想在考虑其他解决方案之前先了解一下它的严重程度。
我说的是从2GB开始的数GB范围内的sqlite数据文件。有人对此有经验吗?有任何提示/想法吗?
Answers:
因此,我使用sqlite对非常大的文件进行了一些测试,并得出了一些结论(至少对于我的特定应用程序而言)。
测试涉及具有单个表或多个表的单个sqlite文件。每个表大约有8列,几乎所有整数和4个索引。
想法是插入足够的数据,直到sqlite文件约为50GB。
单桌
我试图将多个行插入到只有一个表的sqlite文件中。当文件大小约为7GB(对不起,我无法确切说明行数)时,插入时间过长。我估计插入所有数据的测试大约需要24小时,但即使在48小时后仍无法完成。
这使我得出一个结论,即一个非常大的sqlite表在插入操作以及其他操作上也会遇到问题。
我猜这并不奇怪,因为表越来越大,插入和更新所有索引花费的时间更长。
多个表
然后,我尝试按时间将数据分成几张表,每天一张表。原始1个表的数据被拆分为700个表。
由于每天都会创建一个新表,因此该设置在插入时没有问题,并且时间不会花费更长的时间。
真空问题
正如i_like_caffeine所指出的,sqlite文件越大,VACUUM命令就是一个问题。随着更多插入/删除操作的完成,磁盘上文件的碎片将变得更糟,因此目标是定期进行VACUUM优化文件并恢复文件空间。
但是,正如文档所指出的那样,数据库的完整副本是用来进行清理的,需要很长时间才能完成。因此,数据库越小,此操作将完成得越快。
结论
对于我的特定应用程序,我可能会每天将数据拆分成多个db文件,以获得真空性能和插入/删除速度的最佳效果。
这使查询变得复杂,但是对我来说,能够对这么多的数据建立索引是一个值得权衡的选择。另一个优点是,我可以删除整个db文件来删除一天的数据量(这是我的应用程序的常用操作)。
我可能还必须监视每个文件的表大小,以查看速度何时会成为问题。
令人遗憾的是,除了自动真空之外,似乎没有其他增量真空方法。我无法使用它,因为我的清理目标是对文件进行碎片整理(文件空间不是什么大问题),而自动清理不会这样做。实际上,文档表明它可能使碎片变得更糟,因此我不得不定期对文件进行完全清理。
我们正在平台上使用50 GB +的DBS。没有抱怨效果很好。确保您做的一切正确!您是否在使用预定义语句?* SQLITE 3.7.3
应用这些设置(在创建数据库之后)
PRAGMA main.page_size = 4096;
PRAGMA main.cache_size=10000;
PRAGMA main.locking_mode=EXCLUSIVE;
PRAGMA main.synchronous=NORMAL;
PRAGMA main.journal_mode=WAL;
PRAGMA main.cache_size=5000;
希望这对其他人有帮助,在这里能起到很大的作用
PRAGMA main.temp_store = MEMORY;
。
我创建了最大3.5GB的SQLite数据库,没有明显的性能问题。如果我没记错的话,我认为SQLite2可能有一些下限,但我认为SQLite3没有任何此类问题。
根据“ SQLite限制”页面,每个数据库页面的最大大小为32K。数据库中的最大页面数为1024 ^ 3。因此,根据我的数学计算,最大大小为32 TB。我认为您在达到SQLite的标准之前会达到文件系统的极限!
进行插入需要花费48个小时以上的大部分原因是由于您的索引。更快地达到:
1-删除所有索引2-全部插入3-再次创建索引
除了通常的建议:
我从SQLite3的经验中学到了以下内容:
欢迎提问/评论。;-)
我有一个7GB的SQLite数据库。使用内部联接执行特定查询需要2.6秒的时间。为了加快速度,我尝试添加索引。根据我添加的索引,有时查询下降到0.1s,有时上升到7s。我认为我的问题是,如果一列是高度重复的,那么添加索引会降低性能:(
在SQLite文档中曾经有一个声明,即数据库文件的实际大小限制为几十GB:s。这主要是由于SQLite在启动事务时需要“分配脏页的位图”。因此,数据库中的每个MB都需要256字节的RAM。插入到50 GB的DB文件中将需要大量(2 ^ 8)*(2 ^ 10)= 2 ^ 18 = 256 MB的RAM。
但是从最新版本的SQLite开始,不再需要此功能。在这里阅读更多。
2^18
实际上只是256 K.