发现 N+1 问题
识别经典的逐行查询陷阱
发现 N+1 问题 是 CoddyKit 上的免费 Django Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Django Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Django Academy 课程共包含 4 节课。
N+1 是什么意思
N+1 问题指的是:代码先运行一次查询获取列表,然后针对列表中的每个项目再运行一次查询。🐢
它藏在哪里
它通常藏在遍历对象的循环中:每次循环都会悄悄地再次访问数据库中的相关行。
一个小例子
想象一下列出图书并打印每本书的作者。下面的循环看起来很普通,但每一行都会触发一次新的查询。
for book in Book.objects.all():
print(book.author.name)统计查询次数
一次查询会加载所有图书。随后每次访问 book.author 都会运行自己的查询,因此 100 本图书意味着要访问数据库 101 次。
为什么是 1 加 N
这就是名称的由来:父列表需要 1 次查询,再加上每个被访问的相关对象各需一次的 N 次额外查询。
延迟加载是原因
Django 会延迟加载相关行,只有在您请求时才加载。对于单个对象很方便,但在循环中请求时就会很痛苦。
扩展性很差
数据越多,问题越严重。十行数据可能感觉没什么,但一万行数据会将一次页面加载变成查询的洪流。
模板也会触发它
模板在 for 循环中打印相关数据时,也会造成完全相同的查询风暴,即使您看不到 Python 循环。
{% for book in books %}
{{ book.author.name }}
{% endfor %}如何发现它
请注意循环中是否发生了相关对象访问,例如 obj.parent。这种模式每次都是警告信号。
让查询变得可见
在 DEBUG 期间,您可以直接使用 connection.queries 统计查询次数,从而确认一个视图实际进行了多少次往返。
from django.db import connection
print(len(connection.queries))好消息
一旦您能看到问题,Django 就提供了两个工具,可以将所有这些查询压缩为寥寥几次。接下来您将认识它们。🚀
快速检查
让我们确认一下您已经理解 N+1 模式。
回顾
N+1 问题是一次列表查询加上每个相关对象各一次查询,由循环中的延迟加载造成。请观察循环中的相关对象访问来发现它。✅
用 AI 导师学习 Python — 免费
在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。
- 课程
- 30
- 课程
- 120
常见问题解答
「发现 N+1 问题」课时是免费的吗?
是的 — 「发现 N+1 问题」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Django Academy 课程的其余内容,请升级到 CoddyKit PRO。 Django Academy 课程共包含 4 节课。
「发现 N+1 问题」这节课中我会学到什么?
识别经典的逐行查询陷阱 你通过在浏览器中直接运行的动手代码来练习 Django Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Django Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Django Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。
「发现 N+1 问题」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Django Academy 课中编写并运行代码吗?
能。每节 Django Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。