我怎样才能提高django mysql的复制性能?

时间:2015-02-16 17:50:57

标签: python mysql django orm mysql-python

我有一个django应用程序,它定义了一个模型(Person),我也有一些DB(有一个表Appointment),没有定义任何模型(不应该是连接到django应用程序)。

我需要将Appointment表中的一些数据移到Person,以便People表需要镜像Appointment表的所有信息。这是因为有多个独立的数据库,比如Appointment需要复制到Person表中(所以我不想对它的设置方式进行任何体系结构更改)。

img

以下是我现在所做的事情:

res = sourcedb.fetchall() # from Appointment Table
for myrecord in res:
    try:
        existingrecord = Person.objects.filter(vendorid = myrecord[12], office = myoffice)[0]
    except:
        existingrecord = Person(vendorid = myrecord[12], office = myoffice)

    existingrecord.firstname    = myrecord[0]
    existingrecord.midname      = myrecord[1]
    existingrecord.lastname     = myrecord[2]
    existingrecord.address1     = myrecord[3]
    existingrecord.address2     = myrecord[4]
    existingrecord.save()

问题是这太慢了(对于20K记录大约需要8分钟)。我该怎么做才能加快速度呢?

我考虑过以下方法:

1。 bulk_create无法使用此功能,因为我有时需要更新。

2。 delete all然后bulk_create Person模型与其他东西有依赖关系,因此我无法删除Person模型中的记录。

第3。 INSERT ... ON DUPLICATE KEY UPDATE:无法执行此操作,因为Person表的PK与Appointment表PK(主键)不同。约会PK被复制到Person表中。如果有办法检查两个重复的密钥,我认为这种方法可行。

1 个答案:

答案 0 :(得分:0)

一些想法:

  • 编辑:请参阅Trewq对此的评论,并首先在表格上创建索引......
  • 使用with transaction.atomic():在事务中将其全部包装,因为默认情况下,Django会根据save()调用创建一个新事务,这可能会变得非常昂贵。使用20K记录,一个巨大的事务也可能是一个问题,因此您可能必须编写一些代码将事务分成多个批次。试试看吧!
  • 如果RAM不是问题(不应该是具有20k记录的问题),则首先从约会表中获取所有数据,然后使用单个SELECT查询而不是每个记录一个来获取所有现有Person对象
  • 即使其中一些是更新,也请使用bulk_create。这仍然会针对您的更新发出UPDATE个查询,但会将您的所有INSERT个查询减少到只有一个/几个,这仍然是一项改进。您可以通过在调用save()之前插入不具有主键并将插入保存到Python列表中以便稍后bulk_create而不是直接保存它们来区分插入和更新
  • 作为最后的手段:编写原始SQL以使用MySQL INSERT … ON DUPLICATE KEY UPDATE语法。您不需要相同的主键,UNIQUE键就足够了。键可以跨越多列,请参阅Django的Meta.unique_together模型选项。