【问题标题】:Optimizing Django ORM query from multiple DB look-ups to possibly one DB look-up将 Django ORM 查询从多个数据库查找优化到可能的一个数据库查找
【发布时间】:2016-08-16 23:30:01
【问题描述】:

在我维护的一个基于 Django 的社交网站中,用户发布照片。每张发布的照片​​都是一个照片流的一部分(即相关照片的列表)。我通过 CBV (ListView) 的get_queryset 方法计算最近的 200 张照片:

def get_queryset(self):
    return Photo.objects.order_by('-id')[:200]

接下来,对于每张照片,我附加了存在相关照片数量的count。我首先检查每张照片属于哪个照片流,然后从所述流中获取其他照片,最后根据新鲜度排除一些照片。换句话说:

for obj in context["object_list"]:
    count = Photo.objects.filter(which_stream=obj.which_stream).order_by('-upload_time').exclude(upload_time__gt=obj.upload_time).count()

然后将count 与每个obj 配对,这样我就得到了一个用于填充模板的字典。如您所料,我基本上使用此信息来显示相关照片的数量以及每张列出的照片。

但是这样做会导致太多的数据库查找! 我该如何优化它,以获得性能?请指教!

这是具有相关字段的photophotostream 数据模型:

class Photo(models.Model):
    owner = models.ForeignKey(User)
    which_stream = models.ForeignKey(PhotoStream)
    image_file = models.ImageField(upload_to=upload_photo_to_location, storage=OverwriteStorage())
    upload_time = models.DateTimeField(auto_now_add=True, db_index=True)

class PhotoStream(models.Model):
    stream_cover = models.ForeignKey(Photo)
    children_count = models.IntegerField(default=1)
    creation_time = models.DateTimeField(auto_now_add=True)

【问题讨论】:

    标签: python django performance django-models query-performance


    【解决方案1】:

    请检查您是否可以像这样使用Conditional Aggregations

    from django.db.models import Count, Case, When, IntegerField
    
    Photo.objects.annotate(
        count=Count(Case(
            When(which_stream__photo__upload_time__lte=F('upload_time')), then=1),
            output_field=IntegerField(),
        ))
    ).order_by('-id')[:200]
    

    我还没有测试过这个,但我想你会知道如何使用它。

    【讨论】:

      猜你喜欢
      • 2012-11-17
      • 2019-03-30
      • 2016-05-06
      • 2023-03-20
      • 1970-01-01
      • 2018-10-23
      • 2012-11-25
      • 2011-02-27
      • 1970-01-01
      相关资源
      最近更新 更多