专栏名称: Python程序员杂谈
关注PythonWeb开发及相关领域的方方面面,分享在实际工作中遇到的问题及解决方案。关注the5fire,了解Python开发的点点滴滴。
目录
相关文章推荐
环球人物  ·  日本巨头“女太子”,来自中国? ·  17 小时前  
环球人物  ·  “古怪”总统上演“电锯惊魂”? ·  昨天  
南方人物周刊  ·  不卷也不躺,一个小习惯让孩子未来大不同 ·  昨天  
南方人物周刊  ·  黄土高原上种出的果子,到底有多甜? ·  2 天前  
51好读  ›  专栏  ›  Python程序员杂谈

[科普文]什么是ORM中的N+1

Python程序员杂谈  · 公众号  ·  · 2017-06-09 14:59

正文

ORM能够让事情变得简单,也会让有些事情变得复杂。有人说,这不就是一个SQL语句的事嘛,干嘛在ORM里面就这么复杂。

上篇文章我们讲了什么是ORM(对象关系映射),不了解的可以看看上一篇文章。

这篇我们来解释什么是N+1的问题,在所有的ORM中,这都会是一个问题,新手很容易踩到坑。进而导致系统变慢,然后拖垮整个系统。

还是拿代码来说事,上篇我们定义了一个User的模型,这次还继续沿用,然后增加一个Post(文章)的模型。User和Post是一对多的关系,也就是User是Post的外键。代码如下:

  1. from django.db import models

  2. class User(models.Model):

  3.    name = models.CharField(max_length=255)

  4. class Post(models.Model):

  5.    owner = models.ForeignKey(User)   # by the5fire

  6.    title = models.CharField(max_length=255)

  7.    content = models.TextField()

假设我们有这样的代码,现在系统里面有十个用户,每个用户写了一篇文章,也就是十篇文章。

接下来我们有一个需求,展示一个文章列表页,列表页上展示的信息包括:文章标题,文章作者名称。就这两个字段,也不需要分页。

我们要查询出这样的数据要怎么做呢。在ORM的世界中,我们直观的做法是这样:

  1. posts = Post.objects.all()  #  获取所有的文章数据,注意此时不会执行sql语句  by the5fire

  2. result = []

  3. for post in posts:   # 此时会执行select * from post的查询

  4.    result.append({

  5.        'title': post.title,

  6.        'owner': post.owner.name,  # 此时会执行  select * from user where user_id =

  7.    })

写到这就明白了吧。每次循环都要查一下user表,也就是说,如果我第一次查询是10条记录,那么最终我需要执行的查询语句就是10 + 1 = 11条语句。如果我第一次查询出来的是N条记录,那么最终需要执行的sql语句就是N+1次。

这就是N+1的问题。

但是如果懂SQL的话,就知道,其实这就是一个简单的JOIN语句。一条语句就能查出所有的数据,搞什么N+1.

  1. SELECT t1







请到「今天看啥」查看全文


推荐文章
环球人物  ·  日本巨头“女太子”,来自中国?
17 小时前
南方人物周刊  ·  黄土高原上种出的果子,到底有多甜?
2 天前
经典人生感悟  ·  叔叔,你娶我吧!肚子都笑疼了
8 年前
互联网分析沙龙  ·  高手都是这样说话的!
7 年前