defer接口。 把不需要展示的字段做延迟加载。 比如说, 需要获取到文章中除正文外的 其他字段,就可以通过 posts \= Post .objects .all ().defer(' content'),这样拿 到的记录中就不会包含 content 部分。 但是当我们需要用到这个字段时,在使用时会去 加载。 下面还是通过代码演示 :
posts = Post.objects.all().defer('content')
for post in posts: # 此时会执行数据库查询
print(post.content) # 此时会执行数据库查询,获取content
当不想加载某个过大的字段时(如 text 类型的字段),会使用 defer,但是上面的演示代
码会产生 N+l 的查询问题,在实际使用时千万要注意 !
上面的代码是一个不太典型的N+l查询的问题, 一般情况下由外键查询产生的N+I问题 比较多 ,即一条查询请求返回 N 条数据 , 当我们操作数据时 ,又会产 生额外的请求 。 这 就是 N+l 问题 ,所有的 ORM 框架都存在这样的问题。
only接口。 同defer接口刚好相反,如果只想获取到所有的title记录,就可以使用 。口ly,只获取 title 的内容, 其他值在获取时会产生额外的查询。
select_related 接口 。 这就是用来解决外键产生的 N+I 问题的方案 。 我们先来看看什 么情况下会产生这个问题 :
posts = Post.objects.all()
for post in posts: # 产生数据库查询
print(post.onwer) # 产生额外的数据库查询
代码同上面类似,只是这里用的是 owe口r (关联表)。
它的解决方法就是用 select_related 接口 :
post =Post.objects.all() .select_related(’category’)
for post 工n posts #产生数据库查询, category 数据也会一次性查询出未
print(post category)
当然 ,这个接口只能用来解决一对多的关联关系。对于多对多的关系 ,还得使用下面的接口 。
prefetch related 接口 。针对多对多关系的数据,可 以通过这个接口来避免 N+l 查询 。 比如, post和tag的关系可以通过这种方式来避免:
posts = Post.objects.all() .prefetch_related(’tag’)
for post i口 posts: #产生两条查询语句, 分别查询post和tag
print(post.tag.all())
0 Comments latest
No comments.