关于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的Flask框架中实现单元测试的教程
Apr 20 Python
Python实现在matplotlib中两个坐标轴之间画一条直线光标的方法
May 20 Python
python中__slots__用法实例
Jun 04 Python
Python算法应用实战之队列详解
Feb 04 Python
使用pandas把某一列的字符值转换为数字的实例
Jan 29 Python
详解Python 解压缩文件
Apr 09 Python
Python实现Linux监控的方法
May 16 Python
Python 进程操作之进程间通过队列共享数据,队列Queue简单示例
Oct 11 Python
python简单实现最大似然估计&scipy库的使用详解
Apr 15 Python
python argparse传入布尔参数false不生效的解决
Apr 20 Python
MxNet预训练模型到Pytorch模型的转换方式
May 25 Python
python使用BeautifulSoup 解析HTML
Apr 24 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
ThinkPHP采用模块和操作分析
2011/04/18 PHP
关于crontab的使用详解
2013/06/24 PHP
ThinkPHP 3.2 版本升级了哪些内容
2015/03/05 PHP
php动态绑定变量的用法
2015/06/16 PHP
JQuery 写的个性导航菜单
2009/12/24 Javascript
绑定回车enter事件代码
2014/05/18 Javascript
nodejs教程之制作一个简单的文章发布系统
2014/11/21 NodeJs
浅谈Javascript线程及定时机制
2015/07/02 Javascript
使用AmplifyJS组件配合JavaScript进行编程的指南
2015/07/28 Javascript
javascript实现下拉提示选择框
2015/12/29 Javascript
基于JavaScript实现根据手机定位获取当前具体位置(X省X市X县X街道X号)
2015/12/29 Javascript
jQuery弹层插件jquery.fancybox.js用法实例
2016/01/22 Javascript
javaScript 事件绑定、事件冒泡、事件捕获和事件执行顺序整理总结
2016/10/10 Javascript
JS实现动态增加和删除li标签行的实例代码
2016/10/16 Javascript
详解Bootstrap各式各样的按钮(推荐)
2016/12/13 Javascript
浅谈js使用in和hasOwnProperty获取对象属性的区别
2017/04/27 Javascript
详解webpack require.ensure与require AMD的区别
2017/12/13 Javascript
[01:02:06]LGD vs Mineski Supermajor 胜者组 BO3 第二场 6.5
2018/06/06 DOTA
[03:06]2018年度CS GO最具人气解说-完美盛典
2018/12/16 DOTA
python统计字符串中指定字符出现次数的方法
2015/04/04 Python
python版本坑:md5例子(python2与python3中md5区别)
2017/06/20 Python
Flask实现跨域请求的处理方法
2018/09/27 Python
Appium+python自动化怎么查看程序所占端口号和IP
2019/06/14 Python
Python tkinter布局与按钮间距设置方式
2020/03/04 Python
python 8种必备的gui库
2020/08/27 Python
详解Python3 定义一个跨越多行的字符串的多种方法
2020/09/06 Python
HTML5 Canvas实现360度全景图的示例代码
2018/01/29 HTML / CSS
德国街头和运动文化高品质商店:BSTN Store
2017/08/26 全球购物
英国最受欢迎的价格比较网站之一:MoneySuperMarket
2018/12/19 全球购物
法人代表委托书
2014/04/04 职场文书
装饰工程师岗位职责
2014/06/08 职场文书
毕业证丢失证明范本
2014/09/20 职场文书
银行稽核岗位职责
2015/04/13 职场文书
会议主持人开场白台词
2015/05/28 职场文书
培训感想范文
2015/08/07 职场文书
详解Apache SkyWalking 告警配置指南
2021/04/22 Servers