关于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 相关文章推荐
python调用API实现智能回复机器人
Apr 10 Python
python3+PyQt5实现自定义流体混合窗口部件
Apr 24 Python
python面向对象多线程爬虫爬取搜狐页面的实例代码
May 31 Python
python验证码识别教程之利用投影法、连通域法分割图片
Jun 04 Python
基于python实现学生管理系统
Oct 17 Python
对python 调用类属性的方法详解
Jul 02 Python
python KNN算法实现鸢尾花数据集分类
Oct 24 Python
浅谈tensorflow中Dataset图片的批量读取及维度的操作详解
Jan 20 Python
python十进制转二进制的详解
Feb 07 Python
如何在Python对Excel进行读取
Jun 04 Python
PyQt5多线程防卡死和多窗口用法的实现
Sep 15 Python
Python django框架 web端视频加密的实例详解
Nov 20 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在线生成二维码代码(google api)
2013/06/03 PHP
php实现的微信红包算法分析(非官方)
2015/09/25 PHP
thinkphp3.x中display方法及show方法的用法实例
2016/05/19 PHP
PHP中localeconv()函数的用法
2019/03/26 PHP
JavaScript CSS修改学习第三章 修改样式表
2010/02/19 Javascript
仅IE支持clearAttributes/mergeAttributes方法使用介绍
2012/05/04 Javascript
js中call与apply的用法小结
2013/12/28 Javascript
JavaScript 实现简单的倒计时弹窗DEMO附图
2014/03/05 Javascript
javascript的push使用指南
2014/12/05 Javascript
极力推荐一款小巧玲珑的可视化编辑器bootstrap-wysiwyg
2016/05/27 Javascript
jQuery EasyUI Panel面板组件使用详解
2017/02/28 Javascript
Vue2递归组件实现树形菜单
2017/04/10 Javascript
JS实现商品筛选功能
2020/08/19 Javascript
详解微信小程序的 request 封装示例
2018/08/21 Javascript
微信小程序实现时间进度条功能
2020/11/17 Javascript
手动实现vue2.0的双向数据绑定原理详解
2021/02/06 Vue.js
Python之PyUnit单元测试实例
2014/10/11 Python
python中zip()方法应用实例分析
2016/04/16 Python
WINDOWS 同时安装 python2 python3 后 pip 错误的解决方法
2017/03/16 Python
Window10+Python3.5安装opencv的教程推荐
2018/04/02 Python
基于python log取对数详解
2018/06/08 Python
如何基于Python创建目录文件夹
2019/12/31 Python
Python基于codecs模块实现文件读写案例解析
2020/05/11 Python
python 通过pip freeze、dowload打离线包及自动安装的过程详解(适用于保密的离线环境
2020/12/14 Python
基于html5实现的图片墙效果
2014/10/16 HTML / CSS
BISSELL官网:北美吸尘器第一品牌
2019/03/14 全球购物
static关键字的用法
2013/10/07 面试题
怎样有效的进行自我评价
2013/10/06 职场文书
初中三年毕业生的自我评价分享
2014/02/14 职场文书
旅游市场营销方案
2014/03/09 职场文书
社会体育专业大学生职业生涯规划书
2014/09/17 职场文书
专升本学生毕业自我鉴定
2014/10/04 职场文书
2014年学校工作总结
2014/11/20 职场文书
无婚姻登记记录证明
2015/06/18 职场文书
大学开学典礼新闻稿
2015/07/17 职场文书
高效笔记技巧分享:学会这些让你不再困扰
2019/09/04 职场文书