当前位置:首页 > AI技术 > 正文内容

优化核心技巧:Django select related怎么用 一对多查询减少SQL执行次数深度解析 |Duuu笔记

admin6个月前 (04-22)AI技术248

select_related 仅用于正向 ForeignKey 或 OneToOneField 关联,通过 JOIN 避免 N+1 查询;不支持反向关系、多对多字段;嵌套用双下划线;与 values() 等联用时易失效,需谨慎调试 SQL。

什么时候该用

select_related

?

只在「正向 ForeignKey 或 OneToOneField 关联」时才有效,比如

Article.author

(

author

是外键字段)。它通过 SQL 的

JOIN

一次性把关联对象查出来,避免 N+1 查询。

常见错误现象:

for article in Article.objects.all(): print(article.author.name)

会触发 1 次主表查询 + N 次

Author

查询;加了

select_related('author')

后只剩 1 次 JOIN 查询。

不能用于反向关系(如

author.article_set.all()

),那得用

prefetch_related

不支持多对多字段(

ManyToManyField

),哪怕正向定义也不行

如果关联字段允许为空(

null=True

),Django 默认用

INNER JOIN

,可能漏掉主表记录;需显式写

select_related('author__profile')

或改用

select_related('author').filter(author__isnull=False)

select_related

多层嵌套怎么写?

用双下划线连起来就行,比如

select_related('author__profile__avatar')

。Django 会生成多表 LEFT JOIN(只要中间字段允许 null,就自动用 LEFT;否则用 INNER)。

使用场景:用户列表页要显示作者头像、作者所在部门名称,且这些关系都是单向外键链。

每多一层,SQL 中就多一个 JOIN,字段膨胀风险上升——别无脑嵌套 4 层以上

如果某层字段是

OneToOneField

且

null=False

,Django 仍用 INNER JOIN,可能过滤掉数据

注意字段名冲突:比如

author__id

和

id

都存在,QuerySet 返回的

article.id

仍是主表 ID,但底层 SQL 列名会重命名避免冲突,不影响 Python 访问

和

values()

/

values_list()

一起用要注意什么?

一旦调用了

values()

,

select_related

就失效了——因为

values()

只返回字典,不再实例化模型对象,关联对象自然无法懒加载,Django 也就不生成 JOIN。

Action Figure AI

借助Action Figure AI的先进技术,瞬间将照片转化为定制动作人偶。

下载

性能影响明显:你以为加了

select_related

能省 SQL,结果

values('title', 'author__name')

看似等价,实则 Django 内部会忽略

select_related

,改走子查询或干脆不优化。

想取特定字段又想 JOIN,用

only('title', 'author_id')

+

select_related('author')

,再访问

obj.author.name

values_list('title', 'author__name')

是特例:它能触发 JOIN,但返回的是元组,不是模型实例,适合纯数据导出场景

如果已经用了

values()

,又想减少查询,只能手动

annotate()

+

F()

表达式模拟字段拼接

为什么有时候加了

select_related

SQL 没变少?

最常见原因是 QuerySet 被切片、排序或过滤到了关联字段上,导致 Django 放弃 JOIN 优化,退化成子查询。

典型错误场景:

Article.objects.select_related('author').order_by('author__name')[:10]

—— 这个

order_by

引用了外键字段,Django 为保证分页语义正确,会先查出主表 ID,再按 ID 批量查关联对象,变成 2 次查询。

解决办法:换用数据库原生排序(确保

author__name

有索引),或把排序逻辑移到 Python 层(仅限小数据集)

filter(author__name__icontains='x')

不影响

select_related

生效,它只是 WHERE 条件,JOIN 照常

调试技巧:打印

str(qs.query)

看实际 SQL,比猜靠谱得多

Django 的

select_related

是个精准工具,不是银弹。它只解决单向外键链的 N+1,且极易因后续链式操作被悄悄绕过。真正容易被忽略的,是它和

values()

、

order_by()

、

distinct()

这些方法的隐式冲突——这些地方不报错,但优化就没了。

标签: PHP编程技术

相关文章

【大数据分析 | 深度学习】在Hadoop上实现分布式深度学习

一、Submarine(Hadoop生态系统) (一)Submarine 介绍 (三)Submarine 属于 Hadoop 生态系统 (四)Submarine 官网版...

深入理解优化:如何利用 Gemini 3.1 的阶梯计费策略?企业级大规模调用实务完全指南|Duuu笔记

需深入理解Gemini 3.1阶梯计费与调用联动关系,通过识别阶梯区间、请求级Token预估截断、多模型路由调度、响应缓存去重、项目拆分配额绑定五种路径优化成本。 ☞☞☞AI 智能聊天, 问答助手,...

从入门到精通:前端开发之骡子快跑支持热点借势吗 骡子快跑节日营销文案生成|Duuu笔记

骡子快跑平台提供五步节日营销文案生成路径:一、调用内置32个节日模板库;二、输入热点事件触发动态生成;三、绑定自有素材库实现个性化延展;四、多角色视角协同输出;五、接入微信生态直发并校验合规性。 ☞...

深入理解AI:WorkBuddy 怎么做组织架构图 WorkBuddy 组织架构图生成教程【实战】完全指南|Duuu笔记

WorkBuddy可通过四种方式生成组织架构图:一、用自然语言指令触发AI自动解析并渲染Mermaid图表;二、上传Excel结构化数据映射字段后批量构建动态树状图;三、启用OpenClaw技能包对接...

深入理解前端开发:Minimax 视频生成中负面提示词(Negative Prompt)写法完全指南|Duuu笔记

Minimax视频生成中负面提示词需用英文、逗号分隔,支持权重调节(如(blurry:1.3)),按构图/主体/画质/风格四类精简选取,禁用not/no/中文及违规词,须通过A/B测试验证有效性。...

深入理解前端开发:Minimax视频生成黑科技:复杂动作模拟完全指南|Duuu笔记

为精准模拟复杂动作,需采用分帧提示词构建、骨骼关键点引导注入和多阶段动作蒸馏三法:一、将动作拆解为带空间姿态的关键帧序列并加物理约束;二、注入2D/3D关键点坐标锚定关节位置;三、通过粗生成→特征提取...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。