关于Django ForeignKey 反向查询中filter和_set的效率对比详解


Posted in Python onDecember 15, 2018

前言

大家使用 Django 创建模型的时候一定会经常使用 ForeignKey 来创建两个表格之间多对一的外键关系,例如B中有一个 models.ForeignKey(A) 。而当我们需要反向查询 A 中某个具体实例所关联的 B 时,可能会用到 A.B_set.all() 或 B.objects.filter(A) 这两种不同的方法。

不知道大家有没有也想过一个问题:当网站实际上线后,SEO强调页面加载速度,而当面对不断增大的请求量,这两种方法的哪一种速度更快?

馆主我产生了这个疑问,所以就打算跑一下试试看看。馆主尚属小白,如有不对的地方,还请各位客官登录一下账号,留言指点!

实验环境

操作系统: Manjaro Linux 17.1-rc2 
Python: Python 3.6.3 
Django: Django 1.11.7 
数据库: SQLite 3.21.0 
CPU: i3-4130 @ 3.4GHz 
内存: DDR3 1600 8G + 4G

实验计划

分别创建“问题”模型 Questions 和“答案”模型 Answers ,答案模型对于问题模型存在多对一关系 ForeignKey 创建一个问题和两个答案。然后分别使用两种不同的方法运行查询数据 10000 次比较消耗的时间。

实验实施

创建实验模型

# myapp/models.py

from django.db import models

class Questions(models.Model):
  '''问题的模型'''
  title = models.CharField('标题', max_length=100)
  content = models.TextField('描述')


class Answers(models.Model):
  '''答案的模型'''
  question = models.ForeignKey(Questions, on_delete=models.CASCADE, verbose_name='问题')
  content = models.TextField('答案')

然后我们进入 django 的 shell 为模型增加数据并编写我们的测试。

>>> from myapp.models import Questions, Answers

# 创建第一个问题
Questions.objects.create(
  title = '这是第一个问题么?'
  content = '我认为这是第一个问题,不知道是不是真的啊?'
  )

# 创建第一个答案
Answers.objects.create(
  question = Questions.objects.get(pk=1),
  content = '你说对了了,这是第一个问题'
  )


# 创建第二个答案
Answers.objects.create(
  question = Questions.objects.get(pk=1),
  content = '题主,你是第一个问题,但我是第二个答案么?'
  )

利用 timeit 测试两种方法消耗的时间

from timeit import timeit

# 构建使用 _set 方法的函数
def time_test_1():
  question = Question.objects.get(pk=1)
  answers = question.answers_set.all()


# 构建使用 filter 方法的函数
def time_test_2():
  question = Question.objects.get(pk=1)
  answers = Answers.objects.filter(question=question)

# 使用 timeit 测试 10000 次
timeit(time_test_1, number=10000)
5.346277045000534

timeit(time_test_2, number=10000)
5.11136907800028

实际经过多次测试,至少我这样的用法来看 使用A.B_set.all() 反向查询消耗的时间总是比 B.objects.filter(A) 过滤筛选方法多消耗 0.2 - 0.3 秒钟左右。所以但从时间成本来考虑的话还是使用 filter 筛选效率更高一些。

以上这篇关于Django ForeignKey 反向查询中filter和_set的效率对比详解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python3里的super()和__class__使用介绍
Apr 23 Python
Python中的getopt函数使用详解
Jul 28 Python
python中私有函数调用方法解密
Apr 29 Python
Python编程实现的简单神经网络算法示例
Jan 26 Python
TensorFlow搭建神经网络最佳实践
Mar 09 Python
Django数据库连接丢失问题的解决方法
Dec 29 Python
python交易记录链的实现过程详解
Jul 03 Python
Python自动化导出zabbix数据并发邮件脚本
Aug 16 Python
python+opencv3生成一个自定义纯色图教程
Feb 19 Python
python3 sleep 延时秒 毫秒实例
May 04 Python
python3排序的实例方法
Oct 20 Python
python语言time库和datetime库基本使用详解
Dec 25 Python
django 外键model的互相读取方法
Dec 15 #Python
Django之Mode的外键自关联和引用未定义的Model方法
Dec 15 #Python
python调用java的jar包方法
Dec 15 #Python
对python同一个文件夹里面不同.py文件的交叉引用方法详解
Dec 15 #Python
Python数据分析:手把手教你用Pandas生成可视化图表的教程
Dec 15 #Python
浅谈python 导入模块和解决文件句柄找不到问题
Dec 15 #Python
对python当中不在本路径的py文件的引用详解
Dec 15 #Python
You might like
PHP判断JSON对象是否存在的方法(推荐)
2016/07/06 PHP
php+jQuery实现的三级导航栏下拉菜单显示效果
2017/08/10 PHP
一次因composer错误使用引发的问题与解决
2019/03/06 PHP
json数据处理技巧(字段带空格、增加字段、排序等等)
2013/06/14 Javascript
js 跳出页面的frameset框架示例介绍
2013/12/23 Javascript
node.js中的buffer.length方法使用说明
2014/12/14 Javascript
jQuery使用之标记元素属性用法实例
2015/01/19 Javascript
JS实现点击颜色块切换指定区域背景颜色的方法
2015/02/25 Javascript
Angular中$compile源码分析
2016/01/28 Javascript
JavaScript中子对象访问父对象的方式详解
2016/09/01 Javascript
jQuery向webApi提交post json数据
2017/01/16 Javascript
jQuery实现大图轮播
2017/02/13 Javascript
jQuery插件HighCharts绘制2D圆环图效果示例【附demo源码下载】
2017/03/09 Javascript
JS简单验证上传文件类型的方法
2017/04/17 Javascript
利用node.js爬取指定排名网站的JS引用库详解
2017/07/25 Javascript
微信小程序实现点击按钮修改view标签背景颜色功能示例【附demo源码下载】
2017/12/06 Javascript
页面点击小红心js实现代码
2018/05/26 Javascript
详解Vue项目部署遇到的问题及解决方案
2019/01/11 Javascript
js实现web调用摄像头 js截取视频画面
2019/04/21 Javascript
js实现直播点击飘心效果
2020/08/19 Javascript
python简单商城购物车实例代码
2018/03/15 Python
django.db.utils.ProgrammingError: (1146, u“Table‘’ doesn’t exist”)问题的解决
2018/07/13 Python
彻底理解Python中的yield关键字
2019/04/01 Python
selenium+python自动化测试环境搭建步骤
2019/06/03 Python
python中时间转换datetime和pd.to_datetime详析
2019/08/11 Python
TensorFLow 不同大小图片的TFrecords存取实例
2020/01/20 Python
Python利用命名空间解析XML文档
2020/08/10 Python
车间副主任岗位职责
2013/12/24 职场文书
优秀大学生求职自荐信范文
2014/04/19 职场文书
巴西世界杯32强口号
2014/06/05 职场文书
事业单位个人总结
2015/02/12 职场文书
法院个人总结
2015/03/03 职场文书
uniapp开发小程序的经验总结
2021/04/08 Javascript
解析MySQL binlog
2021/06/11 MySQL
Python实现生活常识解答机器人
2021/06/28 Python
python文件与路径操作神器 pathlib
2022/04/01 Python