Django的性能优化

 

一,利用标准数据库优化技术

传统数据库优化技术博大精深,不同的数据库有不同的优化技巧,但重心还是有规则的。在这里算是题外话,挑两点通用的说说:
  索引,给关键的字段添加索引,性能能更上一层楼,如给表的关联字段,搜索频率高的字段加上索引等。Django建立实体的时候,支持给字段添加索引,具体参考Django.db.models.Field.db_index。按照经验,Django建立实体之前应该早想好表的结构,尽量想到后面的扩展性,避免后面的表的结构变得面目全非。
  使用适当字段类型,本来varchar就搞定的字段,就别要text类型,小细节别不关紧要,后头数据量一上去,愈来愈多的数据,小字段很可能是大问题。

二 ,了解Django的QuerySets

  了解Django的QuerySets对象,对优化简单程序有至关重要的作用。QuerySets是有缓存的,一旦取出来,它就会在内存里呆上一段时间,尽量重用它。

# 了解缓存属性:
>>> entry = Entry.objects.get(id=1)
>>> entry.blog # 博客实体第一次取出,是要访问数据库的
>>> entry.blog # 第二次再用,那它就是缓存里的实体了,不再访问数据库
>>> entry = Entry.objects.get(id=1)
>>> entry.authors.all() # 第一次all函数会查询数据库
>>> entry.authors.all() # 第二次all函数还会查询数据库
  • all,count exists是调用函数(需要连接数据库处理结果的),注意在模板template里的代码,模板里不允许括号,但如果使用此类的调用函数,一样去连接数据库的,能用缓存的数据就别连接到数据库去处理结果。还要注意的是,自定义的实体属性,如果调用函数的,记得自己加上缓存策略。
  • 利用好模板的with标签:

模板中多次使用的变量,要用with标签,把它看成变量的缓存行为吧。

  • 使用QuerySets的iterator():   

  通常QuerySets先调用iterator再缓存起来,当获取大量的实体列表而仅使用一次时,缓存行为会耗费宝贵的内存,这时iterator()能帮到你,iterator()只调用iterator而省 去了缓存步骤,显著减少内存占用率,具体参考相关文档。

三, 数据库的工作就交给数据库本身计算,别用Python处理

  • 使用 filter and exclude 过滤不需要的记录,这两个是最常用语句,相当是SQL的where
  • 同一实体里使用F()表达式过滤其他字段
  • 使用annotate对数据库做聚合运算

  不要用python语言对以上类型数据过滤筛选,同样的结果,python处理复杂度要高,而且效率不高, 白白浪费内存

  • 使用QuerySet.extra() extra虽然扩展性不太好,但功能很强大,如果实体里需要需要增加额外属性,不得已时,通过extra来实现,也是个好办法
  • 使用原生的SQL语句 如果发现Django的ORM已经实现不了你的需求,而extra也无济于事的时候,那就用原生SQL语句

四,如果需要就一次性取出你所需要的数据

  单一动作(如:同一个页面)需要多次连接数据库时,最好一次性取出所有需要的数据,减少连接数据库次数。

  此类需求推荐使用QuerySet.select_related() (主动连表)和 prefetch_related()(被动连表)

  相反,别取出你不需要的东西,模版templates里往往只需要实体的某几个字段而不是全部,这时QuerySet.values() 和 values_list(),对你有用,它们只取你需要的字段,返回字典dict和列表list类型的东西,在模版里够用即可,这可减少内存损耗,提高性能

  同样QuerySet.defer()only()对提高性能也有很大的帮助,一个实体里可能有不少的字段,有些字段包含很多元数据,比如博客的正文,很多字符组成,Django获取实体时(取出实体过程中会进行一些python类型转换工作),我们可以延迟大量元数据字段的处理,只处理需要的关键字段,这时QuerySet.defer()就派上用场了,在函数里传入需要延时处理的字段即可;而only()和defer()是相反功能

  使用QuerySet.count()代替len(queryset),虽然这两个处理得出的结果是一样的,但前者性能优秀很多。同理判断记录存在时,QuerySet.exists()比if queryset实在强得太多了

五,懂减少数据库的连接数

  使用 QuerySet.update() 和 delete(),这两个函数是能批处理多条记录的,适当使用它们事半功倍;如果可以,别一条条数据去update delete处理。

  对于一次性取出来的关联记录,获取外键的时候,直接取关联表的属性,而不是取关联属性,如:

entry.blog.id
优于
entry.blog__id # 善于使用批量插入记录,如:
Entry.objects.bulk_create([
Entry(headline="Python 3.0 Released"),
Entry(headline="Python 3.1 Planned")
])
优于
Entry.objects.create(headline="Python 3.0 Released")
Entry.objects.create(headline="Python 3.1 Planned")
# 前者只连接一次数据库,而后者连接两次 # 还有相似的动作需要注意的,如:多对多的关系,
my_band.members.add(me, my_friend)
优于
my_band.members.add(me)
my_band.members.add(my_friend)
 
 
 

Django的性能优化的更多相关文章

  1. Django数据库性能优化之 - 使用Python集合操作

    前言 最近有个新需求: 人员基础信息(记作人员A),10w 某种类型的人员信息(记作人员B),1000 要求在后台上(Django Admin)分别展示:已录入A的人员B列表.未录入的人员B列表 团队 ...

  2. python django ORM 性能优化 select_related & prefetch_related

    q = models.UserInfo.objects.all() select * from userinfo select * from userinfo inner join usertype ...

  3. Django ORM性能优化 和 图片验证码

    一,ORM性能相关 1. 关联外键, 只拿一次数据 all_users = models.User.objects.all().values('name', 'age', 'role__name') ...

  4. Django ORM性能优化之count和len方法的选择(非常详细推荐干货)

    接下来我将从源码层面分情况和应用分析我们在计算queryset数据集时是用orm的count函数计算长度还是用len函数计算数据集长度. 首先,我们知道ORM查询queryset数据集是惰性查询的,只 ...

  5. Django的model查询操作 与 查询性能优化

    Django的model查询操作 与 查询性能优化 1 如何 在做ORM查询时 查看SQl的执行情况 (1) 最底层的 django.db.connection 在 django shell 中使用 ...

  6. Django之使用celery和NGINX生成静态页面实现性能优化

    性能优化原理: 当我们要给client浏览器返回一个页面时,我们需要去数据库查询数据并将数据和基本页面模板渲染形成页面返回给客户端,但如果每一个用户访问时都去查询一次首页的的数据时,当日访问量很大时那 ...

  7. Django 数据库访问性能优化

    使用标准的数据库优化技术: 在进行Django数据库访问性能优化之前,首先应该使用标准的数据库技术对其进行优化,比如给字段加索引,通过使用 django.db.models.Field.db_inde ...

  8. django_orm查询性能优化

    查询操作和性能优化 1.基本操作 增 models.Tb1.objects.create(c1='xx', c2='oo') 增加一条数据,可以接受字典类型数据 **kwargs obj = mode ...

  9. Python Django性能测试与优化指南

    摘要:本文通过一个简单的实例一步一步引导读者对其进行全方位的性能优化.以下是译文. 唐纳德·克努特(Donald Knuth)曾经说过:“不成熟的优化方案是万恶之源.”然而,任何一个承受高负载的成熟项 ...

随机推荐

  1. JavaScript规定了几种语言类型?

    JavaScript中的每一个值都有它自己的类型,JavaScript规定了七种语言类型: 1.Undefined 2.Null 3.Boolean 4.String 5.Number 6.Symbo ...

  2. RocketMQ(1)-架构原理

    RocketMQ(1)-架构原理 RocketMQ是阿里开源的分布式消息中间件,跟其它中间件相比,RocketMQ的特点是纯JAVA实现:集群和HA实现相对简单:在发生宕机和其它故障时消息丢失率更低. ...

  3. 老雷socket编程之websocket实现

    老雷socket编程之websocket实现 我们主要实现私聊和群聊两个功能,要在web端实现想微信QQ那样的即时通讯的功能,我们需要了解一下websocket.websocket是一种可以双向通讯的 ...

  4. 【Idea】JUnit单元测试%MODULE_WORKING_DIR%' does not exist

    Idea执行单元测试时报错:上午9:35 Error running 'MobileMessageImplTest.java': Cannot start process, the working d ...

  5. Python笔记【7】_反射getattr&hasattr&setattr&delattr

    Lesson0402_GetatrrWebsite.py #!/usr/bin/env/python #-*-coding:utf-8-*- #Author:LingChongShi #查看源码Ctr ...

  6. 微服务-springcloud学习资料链接

    API文档:https://springcloud.cc/spring-cloud-dalston.html#_spring_cloud_netflix 中文社区:http://springcloud ...

  7. FireFox下Canvas使用图像合成绘制SVG的Bug

    本文适合适合对canvas绘制.图形学.前端可视化感兴趣的读者阅读. 楔子 所有的事情都会有一个起因.最近产品上需要做一个这样的功能:给一些图形进行染色处理.想想这还不是顺手拈来的事情,早就研究过图形 ...

  8. 开源SQL审核平台——Archery 安装、部署心得

    目录 0.软件版本及项目地址 1.安装python venv环境 1.1.安装 python36 1.2.创建 Python venv 环境(Python>=3.6.5,建议使用虚拟环境 ) 1 ...

  9. HDU 6207:Apple(Java高精度)

    题目链接 题意 给出三个圆上的点,和一个目标的点,问目标点是否在这三个点构成的圆外面. 思路 许久没见过的Java高精度,不要加package!!! import java.math.BigDecim ...

  10. 对http请求进行过滤处理,转换成接收着需要的格式

    需要在Global.asax的Application中进行初始化处理 这样:GlobalConfiguration.Configuration.MessageHandlers.Add(new Defa ...