关于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 相关文章推荐
pygame 精灵的行走及二段跳的实现方法(必看篇)
Jul 10 Python
python 读写中文json的实例详解
Oct 29 Python
使用python对excle和json互相转换的示例
Oct 23 Python
Python中flatten( )函数及函数用法详解
Nov 02 Python
10行Python代码计算汽车数量的实现方法
Oct 23 Python
Python Lambda函数使用总结详解
Dec 11 Python
tensorflow常用函数API介绍
Apr 19 Python
利用matplotlib为图片上添加触发事件进行交互
Apr 23 Python
python 实现读取csv数据,分类求和 再写进 csv
May 18 Python
详解如何在PyCharm控制台中输出彩色文字和背景
Aug 17 Python
python基于scrapy爬取京东笔记本电脑数据并进行简单处理和分析
Apr 14 Python
Python中Numpy和Matplotlib的基本使用指南
Nov 02 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 5.0对象模型深度探索之对象复制
2008/03/27 PHP
发款php蜘蛛统计插件只要有mysql就可用
2010/10/12 PHP
PHP入门教程之字符串处理技巧总结(转换,过滤,解析,查找,截取,替换等)
2016/09/11 PHP
Prototype Hash对象 学习
2009/07/19 Javascript
JQuery 返回布尔值Is()条件判断方法代码
2012/05/14 Javascript
Java 正则表达式学习总结和一些小例子
2012/09/13 Javascript
Visual Studio中js调试的方法图解
2014/06/30 Javascript
jquery和js实现对div的隐藏和显示方法
2014/09/26 Javascript
学习JavaScript设计模式之状态模式
2016/01/08 Javascript
javascript特殊文本输入框网页特效
2016/09/13 Javascript
谈谈对JavaScript原生拖放的深入理解
2016/09/20 Javascript
通过网页查看JS源码中汉字显示乱码的解决方法
2016/10/26 Javascript
Centos7 中安装 Node.js v4.4.4
2016/11/03 Javascript
angularjs实现首页轮播图效果
2017/04/14 Javascript
微信小程序新增的拖动组件movable-view使用教程
2017/05/20 Javascript
详解webpack分离css单独打包
2017/06/21 Javascript
详解使用PM2管理nodejs进程
2017/10/24 NodeJs
Vue的H5页面唤起支付宝支付功能
2019/04/18 Javascript
layui实现二维码弹窗、并下载到本地的方法
2019/09/25 Javascript
使用Element的InfiniteScroll 无限滚动组件报错的解决
2020/07/27 Javascript
Vue $attrs & inheritAttr实现button禁用效果案例
2020/12/07 Vue.js
[00:35]DOTA2上海特级锦标赛 MVP.Phx战队宣传片
2016/03/04 DOTA
举例讲解Python中is和id的用法
2015/04/03 Python
详解python3实现的web端json通信协议
2016/12/29 Python
PyQt5实现简易计算器
2020/05/30 Python
没编程基础可以学python吗
2020/06/17 Python
Pycharm2020.1安装无法启动问题即设置中文插件的方法
2020/08/07 Python
Python获取android设备cpu和内存占用情况
2020/11/15 Python
国际知名军事风格休闲装品牌:Alpha Industries(阿尔法工业)
2017/05/24 全球购物
通息工程毕业生自荐信
2013/10/16 职场文书
遗产继承公证书
2014/04/09 职场文书
早上好问候语大全
2015/11/10 职场文书
我的中国梦心得体会范文
2016/01/05 职场文书
Oracle以逗号分隔的字符串拆分为多行数据实例详解
2021/07/16 Oracle
Python OpenCV实现图像模板匹配详解
2022/04/07 Python
Tomcat执行startup.bat出现闪退的原因及解决办法
2022/04/20 Servers