【问题标题】:How can I improve django mysql copy performance?如何提高 django mysql 复制性能?
【发布时间】:2015-02-16 17:50:56
【问题描述】:

我有一个定义了模型 (Person) 的 django 应用程序,并且我还有一些没有定义任何模型的数据库(其中有一个表 Appointment)(不打算连接到 django应用程序)。

我需要将Appointment 表中的一些数据移动到Person,以便 People 表需要反映 Appointment 表的所有信息。之所以这样,是因为需要将多个独立的数据库(例如 Appointment)复制到 Person 表中(因此我不想对其设置方式进行任何架构更改)。

这是我现在要做的:

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 被复制到人员表中。如果有办法检查两个重复的键,我认为这种方法会起作用。

【问题讨论】:

    标签: python mysql django orm mysql-python


    【解决方案1】:

    一些想法:

    • 编辑:请参阅 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 模型选项。

    【讨论】:

    • 问题只是我需要创建一个索引 - 然后我能够在 76 秒内运行查询,当我使用 atomic() 时,我能够在 56 秒内得到它.
    • 嗯,有时它比人们想象的要容易......
    猜你喜欢
    • 1970-01-01
    • 2015-02-26
    • 2012-07-16
    • 2016-10-07
    • 2012-04-11
    • 2011-09-17
    • 2018-07-11
    • 2018-09-06
    相关资源
    最近更新 更多