Django的性能优化
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的性能优化的更多相关文章
- Django数据库性能优化之 - 使用Python集合操作
前言 最近有个新需求: 人员基础信息(记作人员A),10w 某种类型的人员信息(记作人员B),1000 要求在后台上(Django Admin)分别展示:已录入A的人员B列表.未录入的人员B列表 团队 ...
- python django ORM 性能优化 select_related & prefetch_related
q = models.UserInfo.objects.all() select * from userinfo select * from userinfo inner join usertype ...
- Django ORM性能优化 和 图片验证码
一,ORM性能相关 1. 关联外键, 只拿一次数据 all_users = models.User.objects.all().values('name', 'age', 'role__name') ...
- Django ORM性能优化之count和len方法的选择(非常详细推荐干货)
接下来我将从源码层面分情况和应用分析我们在计算queryset数据集时是用orm的count函数计算长度还是用len函数计算数据集长度. 首先,我们知道ORM查询queryset数据集是惰性查询的,只 ...
- Django的model查询操作 与 查询性能优化
Django的model查询操作 与 查询性能优化 1 如何 在做ORM查询时 查看SQl的执行情况 (1) 最底层的 django.db.connection 在 django shell 中使用 ...
- Django之使用celery和NGINX生成静态页面实现性能优化
性能优化原理: 当我们要给client浏览器返回一个页面时,我们需要去数据库查询数据并将数据和基本页面模板渲染形成页面返回给客户端,但如果每一个用户访问时都去查询一次首页的的数据时,当日访问量很大时那 ...
- Django 数据库访问性能优化
使用标准的数据库优化技术: 在进行Django数据库访问性能优化之前,首先应该使用标准的数据库技术对其进行优化,比如给字段加索引,通过使用 django.db.models.Field.db_inde ...
- django_orm查询性能优化
查询操作和性能优化 1.基本操作 增 models.Tb1.objects.create(c1='xx', c2='oo') 增加一条数据,可以接受字典类型数据 **kwargs obj = mode ...
- Python Django性能测试与优化指南
摘要:本文通过一个简单的实例一步一步引导读者对其进行全方位的性能优化.以下是译文. 唐纳德·克努特(Donald Knuth)曾经说过:“不成熟的优化方案是万恶之源.”然而,任何一个承受高负载的成熟项 ...
随机推荐
- Laravel5.x的php artisan migrate数据库迁移创建操作报错SQLSTATE[42000]解决
Laravel5.x运行迁移命令创建数据表:php artisan migrate报错. Illuminate\Database\QueryException : SQLSTATE[42000]: ...
- [转]Android的taskAffinity
Activity的归属,也就是Activity应该在哪个Task中,Activity与Task的吸附关系.我们知道,一般情况下在同一个应用中,启动的Activity都在同一个Task中,它们在该Tas ...
- 关于exe4j打包问题
一.eclipse导出jar Export-->Runnable JAR file 这里有两种情况: 选择 Package required libraries into generated j ...
- 跟我学SpringCloud | 第三篇:服务的提供与Feign调用
跟我学SpringCloud | 第三篇:服务的提供与Feign调用 上一篇,我们介绍了注册中心的搭建,包括集群环境吓注册中心的搭建,这篇文章介绍一下如何使用注册中心,创建一个服务的提供者,使用一个简 ...
- jQuery调整表列(左右拉动调整列宽)插件__colResizable,动态列如何使用
官网地址:http://www.bacubacu.com/colresizable/ 这里值得注意的是,如果是动态加入的列,则需要先清理调用插件生成的class,id和div之后再重新调用才会有作用. ...
- Python生成word
Python生成word 使用python-docx-template库, 将html转为word. python-docx-template可以使用类似jinja2的模板语法. 依赖docx库, 安 ...
- Cisco packet tracer下dhcp的配置的vlan的应用
话不多说,先上拓扑图. pc0和pc1分别接在三层交换机的F0/1.F0/2接口,ser接在F0/24接口,用ser用作dhcp的服务器. 0x01:配置server0 先配置server的IP地址. ...
- 【Aizu - 0118】Property Distribution
-->Property Distribution 原文是日语,算了算了,直接上我大中华母语吧 Descriptions: 在H * W的矩形果园里有苹果.梨.蜜柑三种果树, 相邻(上下左右)的 ...
- Android使用WebView加载H5页面播放视频音频,退出后还在播放问题解决
Android中经常会使用到WebView来加载H5的页面,如果H5页面中有音频或者视频的播放时,还没播放完就退出界面,这个时候会发现音频或者视频还在后台播放,这就有点一脸懵逼了,下面是解决方案: 方 ...
- Java基础之回味finally
平时大家try…catch…finally语句用的不少,知道finally块一定会在try…catch..执行结束时执行,但是具体是在什么时候执行呢,今天我们一起来看下. public static ...