关于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的一些用法分享
Oct 07 Python
Python 用户登录验证的小例子
Mar 06 Python
Python使用lxml模块和Requests模块抓取HTML页面的教程
May 16 Python
解决Django migrate No changes detected 不能创建表的问题
May 27 Python
python判断计算机是否有网络连接的实例
Dec 15 Python
Python字典对象实现原理详解
Jul 01 Python
Python实现最大子序和的方法示例
Jul 05 Python
Django框架 Pagination分页实现代码实例
Sep 04 Python
selenium与xpath之获取指定位置的元素的实现
Jan 26 Python
Python的flask接收前台的ajax的post数据和get数据的方法
Apr 12 Python
解决python3安装pandas出错的问题
May 20 Python
Python用tkinter实现自定义记事本的方法详解
Mar 31 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编写和读取XML的几种方式
2013/01/12 PHP
PHP 自定义错误处理函数的使用详解
2013/05/10 PHP
php使用数组填充下拉列表框的方法
2015/03/31 PHP
php生成随机数/生成随机字符串的方法小结【5种方法】
2020/05/27 PHP
javascript学习笔记(二) js一些基本概念
2012/06/18 Javascript
Javascript中的关键字和保留字整理
2014/10/16 Javascript
javascript实现判断鼠标的状态
2015/07/10 Javascript
浅谈Nodejs观察者模式
2015/10/13 NodeJs
jQuery form 表单验证插件(fieldValue)校验表单
2016/01/24 Javascript
浅谈javascript alert和confirm的美化
2016/12/15 Javascript
JS正则匹配URL网址的方法(可匹配www,http开头的一切网址)
2017/01/06 Javascript
Vue实现购物车场景下的应用
2017/11/27 Javascript
JS和Canvas实现图片的预览压缩和上传功能
2018/03/30 Javascript
jQuery创建及操作xml格式数据示例
2018/05/26 jQuery
JS中Promise函数then的奥秘探究
2018/07/30 Javascript
利用原生的JavaScript实现简单拼图游戏
2018/11/18 Javascript
详解jQuery中的getAll()和cleanData()
2019/04/15 jQuery
使用Angular material主题定义自己的组件库的配色体系
2019/09/04 Javascript
[41:54]2018DOTA2亚洲邀请赛 4.1 小组赛A组加赛 TNC vs Liquid
2018/04/03 DOTA
基于Python对象引用、可变性和垃圾回收详解
2017/08/21 Python
django重新生成数据库中的某张表方法
2019/08/28 Python
keras自定义回调函数查看训练的loss和accuracy方式
2020/05/23 Python
canvas里面如何基于随机点绘制一个多边形的方法
2018/06/13 HTML / CSS
北美女性服装零售连锁店:maurices
2019/06/12 全球购物
荷兰时尚精品店:Labels Fashion
2020/03/22 全球购物
生物科学系大学生的自我评价
2013/12/20 职场文书
《最后的姿势》教学反思
2014/02/27 职场文书
七一建党日演讲稿
2014/09/05 职场文书
2014年采购工作总结
2014/11/20 职场文书
2014年安全管理工作总结
2014/12/01 职场文书
预备党员群众意见
2015/06/01 职场文书
小学班级标语口号大全
2015/12/26 职场文书
2016年大学生暑期社会实践活动总结
2016/04/06 职场文书
创业计划书之餐饮馄饨店
2019/07/18 职场文书
八年级地理课件资料及考点知识分享
2019/08/30 职场文书
win10此电脑打不开怎么办 win10双击此电脑无响应的解决办法
2022/07/23 数码科技