python - 将 Django ORM 查询从多个数据库查找优化为可能的一个数据库查找

标签 python django performance django-models query-performance

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

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

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

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)

最佳答案

请检查您是否可以使用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]

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

关于python - 将 Django ORM 查询从多个数据库查找优化为可能的一个数据库查找,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36808979/

相关文章:

python - 初始化和销毁​​ Python 多处理 worker

python - Numpy 矢量化以提高性能

django - 基于django orm计算的过滤语句

performance - 大字段名称和日期类型对Elasticsearch的性能影响

c++ - 有没有机会使双线性插值更快?

python - 比 python 中的嵌套循环更快的搜索方式

python - 使用 Python 向 json 对象添加一个元素

Django CSRF 验证失败。请求已中止

python - 为什么我的 Apache 看不到我的媒体文件夹?

python - 如何将列表列表中的值分配给键以在python中创建字典