Django - 非常慢的查询

时间:2014-01-17 10:47:39

标签: python django database-optimization

我创建了一个解析xml文件并在django db(pgsql)中更新或创建数据的模块。

当数据导入/更新完成后,我尝试更新我的对象的一些元数据。

我使用django-mptt作为树结构,我的元数据更新程序用于在我的对象之间创建这样的结构。

真的很慢,用其他外键的数据填充父级需要大约1秒钟。

如何优化此功能?

for index, place in enumerate(Place.objects.filter(type=Place.TOWN, town_id_equal=True)):
    place.parent = place.second_order_division
    place.save()

    print index
    if index % 5000 == 0:
        transaction.commit()
transaction.commit()

transaction.set_autocommit(False)
for index, place in enumerate(Place.objects.filter(type=Place.TOWN, town_id_equal=False,
                                                   parent__isnull=True)):

    place.parent = Place.objects.get(town_id=place.town_id_extra)
    place.save()

    print index
    if index % 5000 == 0:
        transaction.commit()
transaction.commit()


class Place(MPTTModel):
    first_order_division = models.ForeignKey("self", null=True, blank=True, verbose_name=u"Województwo",
                                             related_name="voivodeships")
    second_order_division = models.ForeignKey("self", null=True, blank=True, verbose_name=u"Powiat",
                                              related_name="counties")
    parent = TreeForeignKey('self', null=True, blank=True, related_name='children')

编辑:

我更新了第一个这样的功能:

transaction.set_autocommit(False)
for index, obj in enumerate(Place.objects.filter(type=Place.COUNTY)):
    data = Place.objects.filter(second_order_division=obj, type=Place.TOWN, town_id_equal=True)
    data.update(parent=obj)
    print index
    transaction.commit()

2 个答案:

答案 0 :(得分:1)

您应该进行批量更新like

,而不是使用循环

对于第一个事务,您可以使用此Django查询替换您的事务:

Place.objects.filter(type=Place.TOWN, town_id_equal=True).update(parent=F('second_order_division'))

对于第二笔交易,由于再次查询Place模型,我们无法应用批量更新。 为此你应该做一些事情来保存每次循环时点击'Place.objects.get(town_id = place.town_id_extra)'查询。

或者可以从此blog

获取帮助

答案 1 :(得分:-1)

回答一个更普遍的问题,提高几乎任何类型系统性能的一种策略是:

  

尽量减少系统动态部分之间的互动

就是这样:通过HTTP请求,数据库查询等来最小化交互。在您的情况下,您正在对数据库进行多次查询,这些查询可以轻松地减少到更少(可能是一两个)。