You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何优化Django查询结构或正确使用prefetch_related?附场景代码

优化查询结构与反向关联过滤方案

直接优化过滤逻辑(替代两次查询)

你当前的写法会触发两次数据库查询:第一次获取符合条件的document ID列表,第二次根据ID筛选Document。利用Django的反向关联查询,可以把这两步合并为一次高效查询:

qs = Document.objects.filter(rows__item=item_id).distinct()
  • 这里的rows是DocumentRows中document字段定义的related_name,通过rows__item直接关联到DocumentRows的item字段进行过滤
  • 添加.distinct()是为了避免同一个Document被多次返回(因为一个Document可能对应多个符合item=item_id的DocumentRows)

预取关联的DocumentRows数据(使用prefetch_related)

如果后续需要访问每个Document对应的符合条件的DocumentRows条目,可以用Prefetch对象配合prefetch_related,避免N+1查询问题:

from django.db.models import Prefetch

# 先定义过滤后的DocumentRows查询集
filtered_rows = DocumentRows.objects.filter(item=item_id)
# 预取指定条件的关联数据,同时过滤Document
qs = Document.objects.filter(rows__item=item_id).distinct().prefetch_related(
    Prefetch('rows', queryset=filtered_rows, to_attr='filtered_rows')
)

之后访问document.filtered_rows就能直接拿到该文档下符合item=item_id的所有DocumentRows,无需额外查询。

为什么不用原来的写法?

原代码的values_list + id__in会触发两次查询,且当数据量较大时,ID列表会占用额外内存,合并后的查询利用数据库的JOIN操作,效率更高,也更符合Django ORM的最佳实践。

内容的提问来源于stack exchange,提问作者Ranu Vijay

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 14:28:14