合并SQLite数据库让我抓狂。帮忙吗?

2024-06-26 08:42:53 发布

您现在位置:Python中文网/ 问答频道 /正文

我有32个SQLite(3.7.9)数据库,每个数据库有3个表,我正试图使用我在别处找到的习惯用法合并在一起(每个数据库都有相同的模式):

attach db1.sqlite3 as toMerge;
insert into tbl1 select * from toMerge.tbl1;
insert into tbl2 select * from toMerge.tbl2;
insert into tbl3 select * from toMerge.tbl3;
detach toMerge;

并对整个数据库重复清洗。我使用python和sqlite3模块执行此操作:

^{pr2}$

其中2个表相当小,每db只有50K行,而第三个表(tbl3)更大,大约850-900K行。现在,插入的速度会逐渐减慢,直到我到达第四个数据库时,它们几乎停止(大约每1-3分钟向合并数据库添加一到两个兆字节的文件大小)。如果是python,我甚至尝试过将表作为insert(.insert;.out foo;sqlite3)转储完整.db<;foo是框架,找到了here),并使用sqlite3cli将它们组合在一个bash脚本中,直接完成这项工作,但我遇到了完全相同的问题。在

tbl3的表设置并不是太苛刻—一个包含UUID、两个整数和四个实值的文本字段。我担心的是行的数量,因为我在完全相同的位置(大约四个数据库)遇到了完全相同的问题,而在相同的行数下,各个数据库的文件大小要大一个数量级(我通过存储摘要统计数据而不是原始数据来显著地削减了tbl3的内容)。或者是我做手术的方式?在我把东西扔出窗外之前,谁能解释一下我现在的问题吗?在


Tags: from数据库dbsqlitefooselectsqlite3insert
2条回答

尝试为较大的表添加或删除索引/主键。在

你没有提到你正在使用的操作系统或者数据库文件的大小。Windows可能会对大于2Gb的文件产生问题,具体取决于版本。在

在任何情况下,由于这是一个美化的批处理脚本,为什么不去掉for循环,从sys.argv获取文件名,然后对每个合并数据库运行一次。这样你就永远不必在一个过程中处理过多的内存问题。在

请注意,如果您使用以下内容结束循环,则可能也会修复问题。在

c.close()
completedb.close()

您说当您使用CLI执行此过程并在每次db之后退出时,会发生相同的情况。我假设您是指pythoncli,退出意味着您退出并重新启动Python。如果这是真的,而且每4个数据库仍然会出现一个问题,那么您的SQLITE共享库有问题。不应该是那样的。在

如果我站在您的立场上,我会停止使用attach,只在Python中打开多个连接,然后以每次提交大约1000条记录的方式批量移动数据。它会比您的技术慢,因为所有的数据都会在Python对象中来回移动,但我认为它也会更加可靠。打开完整的数据库,然后循环打开第二个数据库,复制,然后关闭第二个数据库。对于复制,我将对SELECT语句使用OFFSET和LIMIT来处理100条记录的批处理,然后提交,然后重复。 事实上,我也会在复制前计算completedb记录,以及第二个db记录,然后在复制之后对completedb记录进行计数,以确保我已经复制了预期的数量。另外,您将跟踪下一个偏移量的值,我会在提交后立即将其写入一个文本文件,这样我就可以随时中断并重新启动该进程,它将在它停止的地方继续进行。在

相关问题 更多 >