如何提高Django mysql的拷贝性能?

2024-09-27 21:26:41 发布

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

我有一个django应用程序,它定义了一个模型(Person),还有一些DB(在表Appointment)没有定义任何模型(并不意味着要连接到django应用程序)。你知道吗

我需要将一些数据从Appointment表移到Person,这样People表需要的所有信息都可以镜像Appointment表。这样做是因为需要将多个独立的DBs(如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。全部删除然后批量创建其他内容依赖于Person模型,因此无法删除Person模型中的记录。你知道吗

3岁。插入。。。在重复密钥更新时:无法执行此操作,因为Person表的PK与Appointment表的PK(主键)不同。约会主键被复制到Person表中。如果有一种方法可以检查两个重复的键,我认为这种方法会奏效。你知道吗


Tags: django方法模型应用程序定义记录resperson
1条回答
网友
1楼 · 发布于 2024-09-27 21:26:41

一些想法:

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

相关问题 更多 >

    热门问题