关于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解析文件示例
Jan 23 Python
从Python的源码来解析Python下的freeblock
May 11 Python
python 爬虫出现403禁止访问错误详解
Mar 11 Python
python字符串str和字节数组相互转化方法
Mar 18 Python
python实现对excel进行数据剔除操作实例
Dec 07 Python
python 巧用正则寻找字符串中的特定字符的位置方法
May 02 Python
pygame实现简易飞机大战
Sep 11 Python
pycharm中使用anaconda部署python环境的方法步骤
Dec 19 Python
Python文件打开方式实例详解【a、a+、r+、w+区别】
Mar 30 Python
pandas按条件筛选数据的实现
Feb 20 Python
浅谈Python3中datetime不同时区转换介绍与踩坑
Aug 02 Python
Python接口自动化之文件上传/下载接口详解
Apr 05 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
印尼林东PWN黄金曼特宁咖啡豆:怎么冲世界上最醇厚的咖啡冲煮教程
2021/03/03 冲泡冲煮
一个很不错的PHP翻页类
2009/06/01 PHP
PHP 远程文件管理,可以给表格排序,遍历目录,时间排序
2009/08/07 PHP
PHP header函数分析详解
2011/08/06 PHP
PHP文章按日期(月日)SQL归档语句
2012/11/29 PHP
php发送短信验证码完成注册功能
2015/11/24 PHP
不用MOUSEMOVE也能滑动啊
2007/05/23 Javascript
javascript textarea光标定位方法(兼容IE和FF)
2011/03/12 Javascript
THREE.JS入门教程(5)你应当知道的十件事
2013/01/24 Javascript
Js和JQuery获取鼠标指针坐标的实现代码分享
2015/05/25 Javascript
JavaScript合并两个数组并去除重复项的方法
2015/06/13 Javascript
javascript中FOREACH数组方法使用示例
2016/03/01 Javascript
JS动态的把左边列表添加到右边的实现代码(可上下移动)
2016/11/17 Javascript
javascript十六进制数字和ASCII字符之间的转换方法
2016/12/27 Javascript
详解Vue中状态管理Vuex
2017/05/11 Javascript
js 毫秒转天时分秒的实例
2017/11/17 Javascript
Node.js命令行/批处理中如何更改Linux用户密码浅析
2018/07/22 Javascript
jQuery常见的遍历DOM操作详解
2018/09/05 jQuery
javascript设计模式 ? 观察者模式原理与用法实例分析
2020/04/22 Javascript
原生JavaScript实现拖动校验功能
2020/09/29 Javascript
[00:53]2015国际邀请赛 中国区预选赛一触即发
2015/05/14 DOTA
[01:34]DAC2018主赛事第四日五佳镜头 Gh巨牙海民助Miracle-死里逃生
2018/04/07 DOTA
python实现控制台打印的方法
2019/01/12 Python
python编写一个会算账的脚本的示例代码
2020/06/02 Python
对pytorch中x = x.view(x.size(0), -1) 的理解说明
2021/03/03 Python
Html5大文件断点续传实现方法
2015/12/05 HTML / CSS
法国娇韵诗官方旗舰店:Clarins是来自法国的天然护肤品牌
2018/06/30 全球购物
中专生的个人自我评价
2013/12/11 职场文书
快递业务员岗位职责
2014/01/06 职场文书
《蜗牛》教学反思
2014/02/18 职场文书
党员干部观看《周恩来四个昼夜》思想汇报
2014/09/10 职场文书
2015毕业寄语大全
2015/02/26 职场文书
大学生入党群众意见书
2015/06/02 职场文书
英语读书笔记
2015/07/02 职场文书
2016年“5.12”国际护士节活动总结
2016/04/06 职场文书
redis sentinel监控高可用集群实现的配置步骤
2022/04/01 Redis