Python 从数据库B向数据库A添加新的非重复记录的最快方法(两者都是巨大的)

Python 从数据库B向数据库A添加新的非重复记录的最快方法(两者都是巨大的),python,memory-management,duplicate-removal,Python,Memory Management,Duplicate Removal,有两个sqlite数据库A和B,都由1000多万行组成。任务是读取B中的所有记录,如果这些新记录在A中还不存在,则将它们添加到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 =

有两个sqlite数据库A和B,都由1000多万行组成。任务是读取B中的所有记录,如果这些新记录在A中还不存在,则将它们添加到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 64位上总共有16G RAM,顺便问一句,有没有想法让python充分利用这一点


总之,基本上我必须将数据库B分成几个部分来完成这项工作,这是非常无效的,因为B中已经有很多重复项,它们最终被分成不同的部分,每次与数据库A进行比较时都会被处理,那么有没有更快的方法可以做到这一点呢?

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

比如:

ca=db\u a.光标(“选择…”)
cb=db_b.光标(“选择…”)
ra=约取数行()
rb=cb.fetch_行()
而ra和rb:

如果ra,您将如何检查记录是否重复?您是否检查多个字段?我建议只读取主字段并对其进行散列。就像listA有两个字段id和散列键用于您要对照listB检查的字段一样,对listB执行相同的操作,然后比较散列keys@AzadehKhojandi:实际上只有一个字段需要检查。我也不认为哈希键会有帮助,因为它不会解决“内存不足”的问题,这意味着我仍然必须将数据库B分成许多部分来完成这项工作。由于数据库无法跨越2GB RAM边界,所以必须使用file方法。创建两个文件,file-A和file-B,其中包含[value]和[key]。按[value]对每个文件进行排序。问题归结为一次读取两个文件中的一行来查找新记录。@AlvinK:我想整个问题归结为一种有效管理内存的方法。即使创建两个文件,它们仍然太大,无法完全读入内存,因此必须将文件分成若干部分?必须有一个b做这一切的更好方法,要么充分利用大型系统RAM,要么使用更好的算法。@Shane:检查答案,谷歌搜索与nore相关的答案
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()