Django中的select_related与prefetch_related
Django是一个基于Python的网站开发框架,一个很重要的特点就是Battery Included,简单来说就是包含了常规开发中所需要的一切东西,包括但不限于完整的ORM模型、中间件、会话处理、模板语言、路由映射、管理员站点等,大大提高了开发者的开发体验,今天要谈的东西便是属于Django ORM这块中查询集优化的内容。
在实际的开发中,模型之间经常存在复杂的关联关系。在数据量较大的情况下,默认的查询可能面临潜在的性能问题。今天我们就分享一下Django ORM的查询优化。
首先需要明确一点:
Queryset是惰性求值的。
在Django中,所有的Queryset都是惰性的,意思是当创建一个查询集的时候,并没有跟数据库发生任何交互。因此我们可以对查询集进行级联的filter等操作,只有在访问Queryset的内容的时候,Django才会真正进行数据库的访问。而多频率、复杂的数据库查询往往是性能问题最大的根源。
为了方便说明,我们定义以下model:
class A(models.Model):
foo = models.IntegerFiled() class B(models.Model):
a = models.ForeignKey(A, related_name='bs')
关联关系中,外键的查询依然是惰性的。当我们通过外键获取一个关联对象的时候,实际上默认获取的是关联对象的ID。这种情况适用于只需要ID而不需要实际的关联对象的场景,这点在Django的文档中有相关说明:
If you only need a foreign key value, use the foreign key value that is already on the object you’ve got, rather than getting the whole related object and taking its primary key.
不过我们实际开发中,往往需要访问到外键对象的其他属性。如果按照默认的查询方式去遍历取值,那么会造成多次的数据库查询,效率可想而知。
select_related和prefetch_related正是为了解决这个问题,他们可以达到这样的目的:在查询对象集合的时候,把指定的外键对象也一并完整查询加载,避免后续的重复查询。
因此,我们可以通过下面的方式来获取B的外键关系对象A的信息:
1 b = B.objects.select_related('a').all()
2
3 for temp_b in b:
4 print temp_b.a.foo
以上方式,实际上只会触发一次数据库查询,会极大的提升查询性能。
prefetch_related效果和select_related类似,不过使用的场景不同:
1,select_related适用于外键和多对一的关系查询;
2,prefetch_related适用于一对多或者多对多的查询。
Django中的select_related与prefetch_related的更多相关文章
- Django 中的select_related函数优化查询
参考链接: https://blog.csdn.net/secretx/article/details/43964607 在数据库有外键的时候,使用select_related()和prefech_r ...
- Django的 select_related 和 prefetch_related 函数对 QuerySet 查询的优化(三)
4.一些实例 如果我们想要获得所有家乡是湖北的人,最无脑的做法是先获得湖北省,再获得湖北的所有城市,最后获得故乡是这个城市的人.就像这样: 1 2 3 4 5 >>> hb = Pr ...
- Django框架详细介绍---ORM相关操作---select_related和prefetch_related函数对 QuerySet 查询的优化
Django的 select_related 和 prefetch_related 函数对 QuerySet 查询的优化 引言 在数据库存在外键的其情况下,使用select_related()和pre ...
- Django的select_related 和 prefetch_related 函数优化查询
在数据库有外键的时候,使用 select_related() 和 prefetch_related() 可以很好的减少数据库请求的次数,从而提高性能.本文通过一个简单的例子详解这两个函数的作用.虽然Q ...
- Django的 select_related 和 prefetch_related 函数对 QuerySet 查询的优化
引言 在数据库存在外键的其情况下,使用select_related()和prefetch_related()很大程度上减少对数据库的请求次数以提高性能 1.实例准备 模型: from django.d ...
- 转 实例详解Django的 select_related 和 prefetch_related 函数对 QuerySet 查询的优化(三)
这是本系列的最后一篇,主要是select_related() 和 prefetch_related() 的最佳实践. 第一篇在这里 讲例子和select_related() 第二篇在这里 讲prefe ...
- Django中的prefetch_related()函数优化
对于多对多字段(ManyToManyField)和一对多字段, 可以使用prefetch_related()来进行优化 prefetch_related()和select_related()的设计目的 ...
- 深入select_related与prefetch_related函数
阅读博客http://blog.jobbole.com/74881/的笔记 在数据库有外键的时候,使用select_related()和prefetch_related()可以很好的减少数据库请求的次 ...
- Django中的QuerySet查询优化之实例篇
转载的,做个笔记,原文链接 在数据库有外键的时候,使用 select_related() 和 prefetch_related() 可以很好的减少数据库请求的次数,从而提高性能.本文通过一个简单的例子 ...
随机推荐
- scrum 第四次冲刺
一.项目目的 为生活在长大的学生提供方快捷的生活服务,通过帖子发现自己志同道合的朋友,记录自己在长大点滴.本项目的意义在于锻炼团队的scrum能力,加强团队合作能力.确定本项目采用的技术方向:本项目整 ...
- 模拟误删除InnoDB ibdata数据文件恢复
注意:假如误删除 ibdata文件 ,此时千万别把mysqld进程杀死,否则没法挽救. 1.模拟删除ibdata数据文件和重做日志文件: [root@hcdb0 data]# lltotal 4219 ...
- Linux python2.4升级到2.7
yum install gcc-c++ gcc -y mkdir /usr/local/python2.7tar zxvf Python-2.7.11.tgzcd Python-2.7.11/./c ...
- hdu-2197 本原串---枚举因子+容斥定理
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2197 题目大意: 由0和1组成的串中,不能表示为由几个相同的较小的串连接成的串,称为本原串,有多少个 ...
- L2范数惩罚项,高维线性回归
%matplotlib inline import mxnet from mxnet import nd,autograd from mxnet import gluon,init from mxne ...
- mac下配置Node.js开发环境、express安装、创建项目
mac下配置Node.js开发环境.express安装.创建项目 一.node.js的安装 去官网下载对应的平台版本就可以了,https://nodejs.org 二.express安装 sudo n ...
- Windows7安装Envi4.8简体中文破解版
在正式安装前,建议先完整阅读本教程!本教程所使用的是Envi 4.8 32 位安装包,径测试,在64位windows7上可以正常安装使用!本教程就是在64位windows7上安装32位Envi4.8! ...
- Android学习笔记_54_自定义 Widget (Toast)
1.Toast控件: 通过查看源代码,发现Toast里面实现的原理是通过服务Context.LAYOUT_INFLATER_SERVICE获取一个LayoutInflater布局管理器,从而获取一个V ...
- MYSQL添加外键关联
SELECT * from stu st,course co,score sc where st.sid = sc.sid and sc.cid = co.cid 如果我们要给 sid 做一个约束,即 ...
- 自定义AngularJS中的services服务
<!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...