【问题标题】:Optimization of querys in django eliminating querys duplicates优化 django 中的查询,消除查询重复
【发布时间】:2017-12-26 16:52:24
【问题描述】:

我正在尝试获取具有每个类别的产品数量,但每个类别又是其他类别的父类别,所以我想知道有多少孩子有该类别及其子类别,我已经简化了查询通过以下方式达到最大值,但在 django 调试中我一直显示我有 66 个查询重复。

如何消除这些重复?

通过views.py的第一行,他设法获得了一个类别中的产品数量,但问题本质上是告诉他从该类别中返回我和他的女儿。

models.py

class Categoria(models.Model):
   nombre = models.CharField(max_length=200)
   slug = models.SlugField(max_length=100)
   padre = models.ForeignKey('self', blank=True, null=True, 
           related_name='cat_padre')
   pub_date = models.DateTimeField('date published', 
                                    auto_now_add=True)
   upd_date = models.DateTimeField('date updated', auto_now=True)

   def __str__(self):
       return self.nombre + ' ' + self.pais.iso

class Producto(models.Model):
   nombre = models.CharField(max_length=200)
   slug = models.SlugField(max_length=100)
   categoria = models.ForeignKey(Categoria)

views.py

cats = Categoria.objects.annotate(num_productos=Count('producto')).filter(pais__iso=pais, padre__isnull=True).order_by('-num_productos')

for c in cats:
     num_p = Producto.objects.filter(categoria__padre=c).count()
     c.num_productos += num_p

 contexto = {
    'categorias_padre': cats,
}

return render(request, 'web/pruebitas/product.html', contexto)

Django 调试:

SELECT COUNT(*) AS "__count" FROM "web_producto" INNER JOIN "web_categoria" ON ("web_producto"."categoria_id" = "web_categoria"."id") WHERE "web_categoria"."padre_id" = '790 '

复制了 62 次。

Conexión: default
/home/luis/PycharmProjects/lco_web/web/middleware.py in __call__(29)
  response = self.get_response(request)
/home/luis/PycharmProjects/lco_web/web/views.py in index(11)
  return categoria(request, '', '/')
/home/luis/PycharmProjects/lco_web/web/views.py in categoria(170)
  'categorias': categorias(pais, categoria.id if categoria else 0),
/home/luis/PycharmProjects/lco_web/web/views.py in categorias(29)
  num_p = Producto.objects.filter(categoria__padre=c).count()

【问题讨论】:

    标签: django


    【解决方案1】:

    您可以通过使用cat_padreCountdistinct=True 对子类别进行反向查找来实现此目的。

    cats = Categoria.objects.annotate(
        num_productos=Count('cat_padre__producto', distinct=True) + 
                      Count('producto', distinct=True)).filter(
                          pais__iso=pais, padre__isnull=True).order_by('-num_productos')
    

    附:我已经在虚假数据上进行了测试,因此请将您之前获得的数据与返回此查询的数据进行比较。

    【讨论】:

    • 它就像一个魅力。所以我们将加载时间从 1.10 秒减少到 945 毫秒,CPU 使用从 435 毫秒减少到 345 毫秒,这是正确的答案。能否请您更彻底地解释一下您是如何得出这个结论的,如果您可以阅读更多关于它的地方,我想了解更多关于这个主题的信息,因为我对查询的问题非常不满
    • @Luis 我玩过你的模型,django orm 和它构建的 sql。我建议阅读 django 文档,了解他们提供的 queryset 和 orm 函数以及一些关于您的底层数据库的书。
    • 你好@bellum,现在我有一个相关的问题,有超过15000个产品和2500个类别,你提到的查询时间超过4秒,这让网络崩溃了,你可以想到一些想法您如何放置类别和产品以避免这些时间,因为我只需要显示超过 10 个产品的类别,这将是重要的。谢谢和最好的问候。
    • @Luis 嗨。我建议您创建另一个问题,因为我没有时间检查。祝你好运。
    猜你喜欢
    • 2011-05-03
    • 1970-01-01
    • 1970-01-01
    • 2011-10-08
    • 2012-03-19
    • 1970-01-01
    • 2016-12-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多