从数据库 B 将新的非重复记录添加到数据库 A 的最快方法(两者都很大)

Posted

技术标签:

【中文标题】从数据库 B 将新的非重复记录添加到数据库 A 的最快方法(两者都很大)【英文标题】:Fastest way to add new non-duplicated records into database A from database B(both are huge) 【发布时间】:2013-04-25 03:25:10 【问题描述】:

有两个 sqlite 数据库 A 和 B,都包含 10+ 百万行。任务是读取 B 中的所有记录并将这些新记录添加到 A 中(如果它们不存在)。

A 中没有重复,但 B 中有很多重复。

我发现这是一项棘手的工作,因为当 A 和 B 都只包含大约 100 万行时,我所做的只是:

list_from_A = read all rows into a list from database A
list_from_B = read all rows into a list from database B

no_dupe_list = list(set(list_from_A) - set(list_from_B))

append no_dupe_list into database A

现在由于这两个数据库太大而无法全部读入内存,所以我在执行此操作时经常遇到 MemoryError,实际上发生这种情况时只使用了 2G 内存,而我的 win 7 总共有 16G RAM 64位,那么顺便说一下让python充分利用这一点的想法吗?

无论如何,基本上我必须将数据库 B 分成几个部分来完成这项工作,这更加无效,因为 B 中已经有很多重复项,并且它们最终被分成不同的部分,每次比较时都会处理这些部分针对数据库 A,有没有更快的方法来做到这一点?

【问题讨论】:

如何检查记录是否重复?您是否检查多个字段?我建议只阅读主要字段并将它们散列。就像 listA 有两个字段 id 和 hash key 用于您要检查 listB 的字段,对 listB 做同样的事情,然后比较 hash 键 @AzadehKhojandi:实际上只需要检查一个字段。而且我认为哈希键也无济于事,因为它不会解决“内存不足”问题,这意味着我仍然需要将数据库 B 分成很多部分来完成这项工作。 由于 DB 无法跨越 2GB RAM 边界,因此您必须使用文件方法。创建两个文件,file-A 和 file-B,其中包含 [value] 和 [key]。按 [值] 对每个文件进行排序。问题被简化为一次从两个文件中读取一行以查找新记录。 @AlvinK.:我想整个问题归结为一种有效管理内存的方法。即使您创建了两个文件,它们仍然太大而无法完全读入内存,因此可能必须将文件分成几部分?必须有更好的方法来完成这一切,要么充分利用大型系统 RAM,要么采用更好的算法。 @Shane:查看how-to-read-large-file-line-by-line-in-python 的 SO 答案,谷歌获取更多相关答案 【参考方案1】:

可以在两个数据库中为有序 SELECT 制作游标,并通过游标记录“并行”(如在合并排序中)并在数据库 A 中插入缺失的行。最好先将它们插入临时表中( s)不要混淆游标,并且不需要内存使用(2行除外。)

喜欢:

ca = db_a.cursor("SELECT ....")
cb = db_b.cursor("SELECT ....")
ra = ca.fetch_row()
rb = cb.fetch_row()
while ra and rb:
  if ra <= rb:
    last_row_in_new_A = ra
    ra = ca.fetch_row()
  else:  # rb < ra
    if rb != last_row_in_new_A:  # Removes possible duplicates
      insert row rb
      last_row_in_A = rb
    rb = cb.fetch_row()
# Insert remaining rows from B
while rb:
  if rb != last_row_in_new_A:
    insert row rb
    last_row_in_new_A = rb
  rb = cb.fetch_row()

【讨论】:

以上是关于从数据库 B 将新的非重复记录添加到数据库 A 的最快方法(两者都很大)的主要内容,如果未能解决你的问题,请参考以下文章

如何将新的SVG图标添加到字体真棒[重复]

如何从jsf / primefaces中的托管bean向页面添加组件[重复]

将新字典添加到现有字典作为键的值[重复]

将新的字典值列添加到熊猫数据框

如何将新的键:值对添加到已经存在的数组状态变量反应原生

excel怎么快速的将新数据替换旧数据?