Django的性能优化实现解析


Posted in Python onJuly 30, 2019

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

传统数据库优化技术博大精深,不同的数据库有不同的优化技巧,但重心还是有规则的。在这里算是题外话,挑两点通用的说说:

索引,给关键的字段添加索引,性能能更上一层楼,如给表的关联字段,搜索频率高的字段加上索引等。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)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
零基础写python爬虫之抓取糗事百科代码分享
Nov 06 Python
为Python的web框架编写MVC配置来使其运行的教程
Apr 30 Python
python通过定义一个类实例作为ftp回调方法
May 04 Python
Python实现调度算法代码详解
Dec 01 Python
python中set()函数简介及实例解析
Jan 09 Python
实例讲解python中的协程
Oct 08 Python
使用Python的OpenCV模块识别滑动验证码的缺口(推荐)
May 10 Python
Tensorflow模型实现预测或识别单张图片
Jul 19 Python
python实现倒计时小工具
Jul 29 Python
Python pandas对excel的操作实现示例
Jul 21 Python
python线程优先级队列知识点总结
Feb 28 Python
使用pandas模块实现数据的标准化操作
May 14 Python
Python爬虫学习之获取指定网页源码
Jul 30 #Python
django-初始配置(纯手写)详解
Jul 30 #Python
django 单表操作实例详解
Jul 30 #Python
Apache部署Django项目图文详解
Jul 30 #Python
Python 使用list和tuple+条件判断详解
Jul 30 #Python
用python wxpy管理微信公众号并利用微信获取自己的开源数据
Jul 30 #Python
Python实现二叉搜索树BST的方法示例
Jul 30 #Python
You might like
php项目打包方法
2008/02/18 PHP
php源码加密 仿微盾PHP加密专家(PHPCodeLock)
2010/05/06 PHP
使用Sphinx对索引进行搜索
2013/06/25 PHP
WordPress的文章自动添加关键词及关键词的SEO优化
2016/03/01 PHP
PHP实现随机发扑克牌
2020/04/22 PHP
javascript开发随笔一 preventDefault的必要
2011/11/25 Javascript
JS 获取鼠标左右键的键值方法
2014/10/11 Javascript
jQuery EasyUI datagrid实现本地分页的方法
2015/02/13 Javascript
js数组去重的方法汇总
2015/07/29 Javascript
JS+CSS实现仿msn风格选项卡效果代码
2015/10/22 Javascript
JS在onclientclick里如何控制onclick的执行
2016/05/30 Javascript
JS原型链 详解及示例代码
2016/09/06 Javascript
轻松搞定js表单验证
2016/10/13 Javascript
给Easyui-Datebox设置隐藏或者不可用的解决方法
2017/05/26 Javascript
layui radio性别单选框赋值方法
2018/08/15 Javascript
深入浅出 Vue 系列 -- 数据劫持实现原理
2019/04/23 Javascript
手动实现vue2.0的双向数据绑定原理详解
2021/02/06 Vue.js
[01:23:35]Ti4主赛事胜者组 DK vs EG 1
2014/07/19 DOTA
深入Python函数编程的一些特性
2015/04/13 Python
Python双精度浮点数运算并分行显示操作示例
2017/07/21 Python
基于python list对象中嵌套元组使用sort时的排序方法
2018/04/18 Python
Python基于百度AI的文字识别的示例
2018/04/21 Python
python使用PIL模块获取图片像素点的方法
2019/01/08 Python
用python3 返回鼠标位置的实现方法(带界面)
2019/07/05 Python
python按修改时间顺序排列文件的实例代码
2019/07/25 Python
python3实现高效的端口扫描
2019/08/31 Python
Django框架教程之中间件MiddleWare浅析
2019/12/29 Python
英国户外服装、鞋类和设备的领先零售商:Millets
2020/10/12 全球购物
Java和Javasciprt的区别
2012/09/02 面试题
小学美术教学反思
2014/02/01 职场文书
团队激励口号
2014/06/06 职场文书
感恩老师演讲稿600字
2014/08/28 职场文书
个人党性锻炼总结
2015/03/05 职场文书
少儿励志名言(80句)
2019/08/14 职场文书
话题作文之自信作文
2019/11/15 职场文书
python图像处理 PIL Image操作实例
2022/04/09 Python