Django是一个基于Python的网站开发框架,一个很重要的特点就是Battery Included,简单来说就是包含了常规开发中所需要的一切东西,包括但不限于完整的ORM模型、中间件、会话处理、模板语言、路由映射、管理员站点等,大大提高了开发者的开发体验,今天要谈的东西便是属于Django ORM这块中查询集优化的内容。

在实际的开发中,模型之间经常存在复杂的关联关系。在数据量较大的情况下,默认的查询可能面临潜在的性能问题。今天我们就分享一下Django ORM的查询优化。

首先需要明确一点:

Queryset是惰性求值的。

在Django中,所有的Queryset都是惰性的,意思是当创建一个查询集的时候,并没有跟数据库发生任何交互。因此我们可以对查询集进行级联的filter等操作,只有在访问Queryset的内容的时候,Django才会真正进行数据库的访问。而多频率、复杂的数据库查询往往是性能问题最大的根源。

为了方便说明,我们定义以下model:

 class A(models.Model):
foo = models.IntegerFiled() class B(models.Model):
a = models.ForeignKey(A, related_name='bs')

关联关系中,外键的查询依然是惰性的。当我们通过外键获取一个关联对象的时候,实际上默认获取的是关联对象的ID。这种情况适用于只需要ID而不需要实际的关联对象的场景,这点在Django的文档中有相关说明:

If you only need a foreign key value, use the foreign key value that is already on the object you’ve got, rather than getting the whole related object and taking its primary key.

不过我们实际开发中,往往需要访问到外键对象的其他属性。如果按照默认的查询方式去遍历取值,那么会造成多次的数据库查询,效率可想而知。

select_related和prefetch_related正是为了解决这个问题,他们可以达到这样的目的:在查询对象集合的时候,把指定的外键对象也一并完整查询加载,避免后续的重复查询。

因此,我们可以通过下面的方式来获取B的外键关系对象A的信息:

1 b = B.objects.select_related('a').all()
2
3 for temp_b in b:
4 print temp_b.a.foo

以上方式,实际上只会触发一次数据库查询,会极大的提升查询性能。

prefetch_related效果和select_related类似,不过使用的场景不同:

1,select_related适用于外键和多对一的关系查询;

2,prefetch_related适用于一对多或者多对多的查询。

 
 
 
 

Django中的select_related与prefetch_related的更多相关文章

  1. Django 中的select_related函数优化查询

    参考链接: https://blog.csdn.net/secretx/article/details/43964607 在数据库有外键的时候,使用select_related()和prefech_r ...

  2. Django的 select_related 和 prefetch_related 函数对 QuerySet 查询的优化(三)

    4.一些实例 如果我们想要获得所有家乡是湖北的人,最无脑的做法是先获得湖北省,再获得湖北的所有城市,最后获得故乡是这个城市的人.就像这样: 1 2 3 4 5 >>> hb = Pr ...

  3. Django框架详细介绍---ORM相关操作---select_related和prefetch_related函数对 QuerySet 查询的优化

    Django的 select_related 和 prefetch_related 函数对 QuerySet 查询的优化 引言 在数据库存在外键的其情况下,使用select_related()和pre ...

  4. Django的select_related 和 prefetch_related 函数优化查询

    在数据库有外键的时候,使用 select_related() 和 prefetch_related() 可以很好的减少数据库请求的次数,从而提高性能.本文通过一个简单的例子详解这两个函数的作用.虽然Q ...

  5. Django的 select_related 和 prefetch_related 函数对 QuerySet 查询的优化

    引言 在数据库存在外键的其情况下,使用select_related()和prefetch_related()很大程度上减少对数据库的请求次数以提高性能 1.实例准备 模型: from django.d ...

  6. 转 实例详解Django的 select_related 和 prefetch_related 函数对 QuerySet 查询的优化(三)

    这是本系列的最后一篇,主要是select_related() 和 prefetch_related() 的最佳实践. 第一篇在这里 讲例子和select_related() 第二篇在这里 讲prefe ...

  7. Django中的prefetch_related()函数优化

    对于多对多字段(ManyToManyField)和一对多字段, 可以使用prefetch_related()来进行优化 prefetch_related()和select_related()的设计目的 ...

  8. 深入select_related与prefetch_related函数

    阅读博客http://blog.jobbole.com/74881/的笔记 在数据库有外键的时候,使用select_related()和prefetch_related()可以很好的减少数据库请求的次 ...

  9. Django中的QuerySet查询优化之实例篇

    转载的,做个笔记,原文链接 在数据库有外键的时候,使用 select_related() 和 prefetch_related() 可以很好的减少数据库请求的次数,从而提高性能.本文通过一个简单的例子 ...

随机推荐

  1. March 15 2017 Week 11 Wednesday

    The starting point of all achievements is desire. 成功的第一步是渴望. Only you desire for somethings, you can ...

  2. SpringBoot应用和PostgreSQL数据库部署到Kubernetes上的一个例子

    创建一个名为ads-app-service的服务: 上述Service的yaml文件里每个字段,在Kubernetes的API文档里有详细说明. https://kubernetes.io/docs/ ...

  3. 手机验证码免费10条\java、C#、html....

    使用互亿无线短信接口网址:http://www.ihuyi.com/. 首先第一步,进行注册 第二步:注册成功后进来的页面 第三步:实名认证 第四步:个人信息 等待认证成功后才能继续操作 第五步:进行 ...

  4. c# 常见验证邮箱、电话号码、日期等格式

    #region 验证邮箱验证邮箱 /**//// <summary> /// 验证邮箱 /// </summary> /// <param name="sour ...

  5. 写到 HTML 文档

    <!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...

  6. git submodule update --init --recursive

    最近在跑好几个模型,视频检测,物体检测,搭建mxnet时,有点问题,记录一下. 视频检测,mxnet需要用指定版本,git 切换到指定版本后,update了,但是依然提示说有些库找不到.想了想,应该是 ...

  7. papers-06-07

    A simple neural network module for relational reasoning Visual Interaction Networks 今天被这两篇文章的工作刷屏,说实 ...

  8. java的异常分类

    结构关系 throwable error   exception checked异常 runtime异常 checked异常也叫io异常这种异常一般我们会在程序块加入trycatch处理它. runt ...

  9. Linux修改时区以及同步时间

    Centos7为例:修改时区 timedatectl list-timezones |grep Shanghai #查找中国时区的完整名称 Asia/Shanghai timedatectl set- ...

  10. #leetcode刷题之路6- Z 字形变换

    将一个给定字符串根据给定的行数,以从上往下.从左到右进行 Z 字形排列.比如输入字符串为 "LEETCODEISHIRING" 行数为 3 时,排列如下:L     C     I ...