优化 django 数据库查询

Posted

技术标签:

【中文标题】优化 django 数据库查询【英文标题】:Optimizing django db queries 【发布时间】:2019-03-30 01:25:49 【问题描述】:

我正在尝试在 django 应用程序中优化我的数据库查询(mysql)。

情况是这样的:

我需要按月检索一些有关销售、某些产品库存的数据。这是函数

def get_magazzino_month(year, month):
    from magazzino.models import ddt_in_item, omaggi_item, inventario_item
    from corrispettivi.models import corrispettivi_item, corrispettivi
    from fatture.models import fatture_item, fatture, fatture_laboratori_item
    from prodotti.models import prodotti
    qt = 0
    val = 0

    products = prodotti.objects.all()
    invents = inventario_item.objects.all().filter(id_inventario__data__year=year-1)
    fatture_lab = fatture_laboratori_item.objects.all().order_by("-id_fattura__data")

    for product in products:
        inv_instance = filter_for_product(invents, product)
        if inv_instance:
            qt += inv_instance[0].quantita
        lab_instance = fatture_lab.filter(id_prodotti=product).first()
        prezzo_prodotto = (lab_instance.costo_acquisto/lab_instance.quantita - ((lab_instance.costo_acquisto/lab_instance.quantita) * lab_instance.sconto / 100)) if lab_instance else product.costo_acquisto
    return val, qt

问题是我需要过滤所有数据以仅获取我需要的产品。似乎 .filter 选项使 django 重新查询数据库,尽管所有数据都在那里。我尝试自己创建一个函数来过滤它,但是尽管查询减少了,但加载时间却大大增加了。

这是要过滤的函数:

def filter_for_product(array, product):
    result = []
    for instance in array:
        if instance.id_prodotti.id == product.id:
            result.append(instance)
    return result

有没有人处理过这种问题?

【问题讨论】:

我很难理解您的问题。但是对于出现在循环之前的invents=...fatture_lab=...,您可以从它们中删除.all()。只需使用objects.filter(...)objects.order_by(..) 问题是我的数据处理时间太长,我认为这来自于正在完成的大量查询。我修改了 invents 和 fatture_lab,谢谢。 【参考方案1】:

您可以使用prefetch_related() 返回相关对象的查询集,使用Prefetch() 进一步控制操作。

from django.db.models import Prefetch

products = prodotti.objects.all().annotate(
    Prefetch(
        'product_set',
        queryset=inventario_item.objects.all().filter(id_inventario__data__year=year-1),
        to_attr='invent'
    )
)

然后您可以访问每个产品的发明,例如products[0].invent

【讨论】:

【参考方案2】:

使用select_related() 将有助于优化您的查询

simpleisbetterthancomplex 提供了有关 select_related() 的作用以及如何使用它的一个很好的示例。

【讨论】:

以上是关于优化 django 数据库查询的主要内容,如果未能解决你的问题,请参考以下文章

从多个模型中获取信息时优化 django 查询

Django Rest Framework,数据库查询优化

在 Django REST 框架中优化数据库查询

django查询优化——啥时候用sql,啥时候用python

Django中的查询优化

Django查询数据库性能优化