关于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 MD5文件生成码
Jan 12 Python
给Python的Django框架下搭建的BLOG添加RSS功能的教程
Apr 08 Python
python 排序算法总结及实例详解
Sep 28 Python
Pycharm编辑器技巧之自动导入模块详解
Jul 18 Python
pandas 两列时间相减换算为秒的方法
Apr 20 Python
PyQt5 QListWidget选择多项并返回的实例
Jun 17 Python
python 命令行传入参数实现解析
Aug 30 Python
150行python代码实现贪吃蛇游戏
Apr 24 Python
Python自定义聚合函数merge与transform区别详解
May 26 Python
opencv+python实现鼠标点击图像,输出该点的RGB和HSV值
Jun 02 Python
面向新手解析python Beautiful Soup基本用法
Jul 11 Python
Python解析m3u8拼接下载mp4视频文件的示例代码
Mar 03 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 对输入信息的进行安全过滤的函数代码
2012/06/29 PHP
PHP中把错误日志保存在系统日志中(Windows系统)
2015/06/23 PHP
实例讲解PHP验证邮箱是否合格
2019/01/28 PHP
Laravel项目中timeAgo字段语言转换的改善方法示例
2019/09/16 PHP
php array_map()函数实例用法
2021/03/03 PHP
javaScript 数值型和字符串型之间的转换
2009/07/25 Javascript
JavaScript经典效果集锦
2010/07/06 Javascript
jquery 单击li防止重复加载的实现代码
2010/12/24 Javascript
juqery 学习之六 CSS--css、位置、宽高
2011/02/11 Javascript
js查错流程归纳
2012/05/04 Javascript
用js读、写、删除Cookie代码分享及详细注释说明
2014/06/05 Javascript
Javascript实现的简单右键菜单类
2015/09/23 Javascript
JavaScript中的return语句简单介绍
2015/12/07 Javascript
怎么限制input的text里输入的值只能是数字(正则、js)
2016/05/16 Javascript
jQuery+Ajax实现限制查询间隔的方法
2016/06/07 Javascript
AngularJS国际化详解及示例代码
2016/08/18 Javascript
nodejs基础应用
2017/02/03 NodeJs
js实现图片加载淡入淡出效果
2017/04/07 Javascript
JavaScript代码判断输入的字符串是否含有特殊字符和表情代码实例
2017/08/17 Javascript
Vue表单demo v-model双向绑定问题
2018/06/29 Javascript
微信小程序实现图片上传
2019/05/23 Javascript
JS控制只能输入数字并且最多允许小数点两位
2019/11/24 Javascript
[57:24]LGD vs VGJ.T 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
视觉直观感受若干常用排序算法
2017/04/13 Python
python实现自动网页截图并裁剪图片
2018/07/30 Python
Django分页查询并返回jsons数据(中文乱码解决方法)
2018/08/02 Python
python字典一键多值实例代码分享
2019/06/14 Python
梅尔倒谱系数(MFCC)实现
2019/06/19 Python
Python之Sklearn使用入门教程
2021/02/19 Python
详解使用CSS3的@media来编写响应式的页面
2017/11/01 HTML / CSS
法国高保真音响和家庭影院商店:Son Video
2019/04/26 全球购物
爱尔兰电脑、家电和家具购物网站:Buy It Direct
2019/07/09 全球购物
中学教师岗位职责
2013/11/26 职场文书
新春文艺演出主持词
2014/03/27 职场文书
理财学专业自荐书
2014/06/28 职场文书
领导班子四风查摆对照检查材料思想汇报
2014/10/05 职场文书