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

优化Django API查询以减少数据库访问次数的方案咨询

Django API数据库查询优化方案

1. CustomUser表查询优化

你可以使用Django ORM的Subquery+OuterRef实现关联过滤,无需单独查询CustomUser表,直接在Product查询中嵌入用户范围的判断逻辑,将两次独立查询合并为单次查询:

from django.db.models import Subquery, OuterRef, F
from django.contrib.gis.measure import D

# 直接在Product过滤逻辑中关联CustomUser表,无需单独拉取用户对象
query_of_set = queryset_list.filter(
    point__distance_lte=(
        Subquery(CustomUser.objects.filter(uid=uid).values("point")[:1]),
        D(km=Subquery(CustomUser.objects.filter(uid=uid).values("discovery_range")[:1]))
    )
)

该写法会把CustomUser的查询转为子查询嵌入SQL,不会产生独立的CustomUser查询请求。

2. 避免count()额外查询的方案

有两种常用方案可选,可根据你的业务逻辑选择:

  • 提前求值方案:如果你后续需要返回该查询集的结果,可以先将查询集转为列表完成一次数据库请求,再用len()判断长度,全程只会产生1次查询:
    range_result = list(query_of_set)
    if len(range_result) < 3:
        # 不足3条时走fallback逻辑
        if query and len(query) > 0:
            query_of_set = queryset_list.filter(lookups).distinct()
        else:
            query_of_set = queryset_list
    else:
        # 数量足够时直接使用已查询到的结果
        query_of_set = range_result
    
  • 轻量统计方案:如果不想提前求值,可以用切片限制count的统计范围,数据库只会扫描到符合条件的3条记录就终止统计,比全量count()性能提升数倍:
    if query_of_set[:3].count() < 3:
        # 执行fallback逻辑
    

3. prefetch_related之外的优化空间

除了prefetch_related外,还有以下优化方向:

  • 对于正向外键/一对一关联,优先使用select_related代替prefetch_related,select_related通过JOIN合并查询,只会产生1次数据库请求,比prefetch_related的独立IN查询效率更高
  • 自定义预取逻辑:使用Prefetch对象指定预取的过滤条件、排序规则,只拉取业务需要的关联数据,减少数据传输量:
    from django.db.models import Prefetch
    # 示例:仅预取已审核的商品评论
    queryset = Product.objects.active().prefetch_related(
        Prefetch("comments", queryset=Comment.objects.filter(is_approved=True), to_attr="approved_comments")
    )
    
  • 索引优化:你当前的搜索逻辑用了多个icontains模糊匹配,建议对搜索字段加全文索引,比如PostgreSQL的GIN索引配合Django内置的全文搜索功能,大幅提升查询速度
  • 缓存优化:如果商品、评论等数据更新频率不高,可以对查询结果或者序列化后的接口返回结果加缓存,高频请求直接走缓存,无需访问数据库

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 17:33:03