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

如何将Django三级关联模型迭代的3次SELECT查询优化至2次及以下?

优化Django链式外键查询至1次SELECT

针对你的模型结构,从Country出发使用嵌套prefetch_related会产生3次查询的原因是:

  1. 第一次查询所有Country
  2. 第二次查询所有关联的State
  3. 第三次查询所有关联的City

要将查询次数优化到1次,可以换查询起点,从最底层的City模型发起查询,利用select_related一次性拉取所有关联对象,再在Python层面重组层级结构:

实现步骤

1. 单次查询获取所有关联数据

City到State、State到Country都是正向外键关联,使用select_related('state__country')可以通过SQL JOIN一次性拉取所有关联数据,仅产生1次SELECT查询:

cities = City.objects.select_related('state__country').all()

2. 在Python层面重组层级结构

用字典将查询结果整理为Country → State → [City]的层级,方便迭代输出:

from collections import defaultdict

# 构建层级映射
country_state_cities = defaultdict(lambda: defaultdict(list))
for city in cities:
    country = city.state.country
    state = city.state
    country_state_cities[country][state].append(city)

# 迭代输出
for country, states in country_state_cities.items():
    for state, city_list in states.items():
        for city in city_list:
            print(country, state, city)

备选方案(2次查询)

如果坚持从Country出发,可以通过自定义Prefetch对象优化,将查询次数减少至2次:

from django.db.models import Prefetch

# 预获取每个State对应的City集合
state_prefetch = Prefetch(
    'state_set',
    queryset=State.objects.prefetch_related('city_set')
)

# 查询Country并关联预获取的State+City数据
countries = Country.objects.prefetch_related(state_prefetch).all()

# 迭代输出
for country in countries:
    for state in country.state_set.all():
        for city in state.city_set.all():
            print(country, state, city)

这种方式会执行2次查询:一次查Country,一次批量查所有关联的State和City。

内容的提问来源于stack exchange,提问作者Super Kai - Kazuya Ito

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 02:50:42