关于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中的多线程编程
Apr 09 Python
Python 专题六 局部变量、全局变量global、导入模块变量
Mar 20 Python
Python实现简单过滤文本段的方法
May 24 Python
django 将model转换为字典的方法示例
Oct 16 Python
详解django+django-celery+celery的整合实战
Mar 19 Python
计算机二级python学习教程(1) 教大家如何学习python
May 16 Python
计算机二级python学习教程(2) python语言基本语法元素
May 16 Python
Python实现的服务器示例小结【单进程、多进程、多线程、非阻塞式】
May 23 Python
python 整数越界问题详解
Jun 27 Python
Python数据持久化存储实现方法分析
Dec 21 Python
如何基于python测量代码运行时间
Dec 25 Python
Python numpy矩阵处理运算工具用法汇总
Jul 13 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 file_get_contents 函数超时的几种解决方法
2009/07/30 PHP
解析php中获取系统信息的方法
2013/06/25 PHP
9段PHP实用功能的代码推荐
2014/10/14 PHP
php gd等比例缩放压缩图片函数
2016/06/12 PHP
Javascript中的相等与不等运算
2010/04/25 Javascript
js multiple全选与取消全选实现代码
2012/12/04 Javascript
js绑定事件this指向发生改变的问题解决方法
2013/04/23 Javascript
jquery 3D 标签云示例代码
2014/06/12 Javascript
Highcharts使用简例及异步动态读取数据
2015/12/30 Javascript
React.js入门学习第一篇
2016/03/30 Javascript
Vue.js系列之项目结构说明(2)
2017/01/03 Javascript
JS中获取 DOM 元素的绝对位置实例详解
2018/04/23 Javascript
webpack4.x CommonJS模块化浅析
2018/11/09 Javascript
详解vue-cli+es6引入es5写的js(两种方法)
2019/04/19 Javascript
原生js实现3D轮播图
2020/03/21 Javascript
jquery实现进度条状态展示
2020/03/26 jQuery
js实现复制粘贴的两种方法
2020/12/04 Javascript
[55:04]海涛DOTA2死魂复燃6.82版本介绍
2014/09/28 DOTA
基于Python实现的微信好友数据分析
2018/02/26 Python
如何优雅地处理Django中的favicon.ico图标详解
2018/07/05 Python
pytorch 自定义数据集加载方法
2019/08/18 Python
Python数据分析pandas模块用法实例详解
2019/11/20 Python
python sitk.show()与imageJ结合使用常见的问题
2020/04/20 Python
200行python代码实现贪吃蛇游戏
2020/04/24 Python
pycharm实现print输出保存到txt文件
2020/06/01 Python
Book Depository澳大利亚:世界领先的专业在线书店之一
2018/12/27 全球购物
给朋友的道歉信
2014/01/09 职场文书
城建学院毕业生自荐信
2014/01/31 职场文书
党校培训自我鉴定范文
2014/03/20 职场文书
法人授权委托书格式
2014/04/08 职场文书
公共场所禁烟标语
2014/06/25 职场文书
新员工考核评语
2014/12/31 职场文书
2015秋季田径运动会广播稿
2015/08/19 职场文书
信息技术远程培训心得体会
2016/01/09 职场文书
Python制作表白爱心合集
2022/01/22 Python
bootstrapv4轮播图去除两侧阴影及线框的方法
2022/02/15 HTML / CSS