django_orm查询性能优化方法


Posted in Python onAugust 20, 2018

查询操作和性能优化

1.基本操作

models.Tb1.objects.create(c1='xx', c2='oo') 增加一条数据,可以接受字典类型数据 **kwargs
 
obj = models.Tb1(c1='xx', c2='oo')
obj.save()

models.Tb1.objects.get(id=123)     # 获取单条数据,不存在则报错(不建议)
models.Tb1.objects.all()        # 获取全部
models.Tb1.objects.filter(name='seven') # 获取指定条件的数据
models.Tb1.objects.exclude(name='seven') # 获取指定条件的数据


models.Tb1.objects.filter(name='seven').delete() # 删除指定条件的数据


models.Tb1.objects.filter(name='seven').update(gender='0') # 将指定条件的数据更新,均支持 **kwargs
obj = models.Tb1.objects.get(id=1)
obj.c1 = '111'
obj.save()                         # 修改单条数据

2.Foreign key的使用原因

  • 约束
  • 节省硬盘

但是多表查询会降低速度,大型程序反而不使用外键,而是用单表(约束的时候,通过代码判断)

extra

extra(self, select=None, where=None, params=None, tables=None, order_by=None, select_params=None)
  Entry.objects.extra(select={'new_id': "select col from sometable where othercol > %s"}, select_params=(1,))
  Entry.objects.extra(where=['headline=%s'], params=['Lennon'])
  Entry.objects.extra(where=["foo='a' OR bar = 'a'", "baz = 'a'"])
  Entry.objects.extra(select={'new_id': "select id from tb where id > %s"}, select_params=(1,), order_by=['-nid'])

F查询

from django.db.models import F
  models.Tb1.objects.update(num=F('num')+1)

Q查询

方式一:

Q(nid__gt=10)
  Q(nid=8) | Q(nid__gt=10)
  Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root')

方式二:
 

con = Q()
  q1 = Q()
  q1.connector = 'OR'
  q1.children.append(('id', 1))
  q1.children.append(('id', 10))
  q1.children.append(('id', 9))
  q2 = Q()
  q2.connector = 'OR'
  q2.children.append(('c1', 1))
  q2.children.append(('c1', 10))
  q2.children.append(('c1', 9))
  con.add(q1, 'AND')
  con.add(q2, 'AND')
 
  models.Tb1.objects.filter(con)

exclude(self, *args, **kwargs)

# 条件查询
 # 条件可以是:参数,字典,Q

select_related(self, *fields)

性能相关:表之间进行join连表操作,一次性获取关联的数据。

model.tb.objects.all().select_related()
  model.tb.objects.all().select_related('外键字段')
  model.tb.objects.all().select_related('外键字段__外键字段')

prefetch_related(self, *lookups)

性能相关:多表连表操作时速度会慢,使用其执行多次SQL查询  在内存中做关联,而不会再做连表查询

# 第一次 获取所有用户表
# 第二次 获取用户类型表where id in (用户表中的查到的所有用户ID)
models.UserInfo.objects.prefetch_related('外键字段')

annotate(self, *args, **kwargs)

# 用于实现聚合group by查询
from django.db.models import Count, Avg, Max, Min, Sum
 v = models.UserInfo.objects.values('u_id').annotate(uid=Count('u_id'))
# SELECT u_id, COUNT(ui) AS `uid` FROM UserInfo GROUP BY u_id
v = models.UserInfo.objects.values('u_id').annotate(uid=Count('u_id')).filter(uid__gt=1)
# SELECT u_id, COUNT(ui_id) AS `uid` FROM UserInfo GROUP BY u_id having count(u_id) > 1
v = models.UserInfo.objects.values('u_id').annotate(uid=Count('u_id',distinct=True)).filter(uid__gt=1)
# SELECT u_id, COUNT( DISTINCT ui_id) AS `uid` FROM UserInfo GROUP BY u_id having count(u_id) > 1

extra(self, select=None, where=None, params=None, tables=None, order_by=None, select_params=None)

# 构造额外的查询条件或者映射,如:子查询
Entry.objects.extra(select={'new_id': "select col from sometable where othercol > %s"}, select_params=(1,))
Entry.objects.extra(where=['headline=%s'], params=['Lennon'])
Entry.objects.extra(where=["foo='a' OR bar = 'a'", "baz = 'a'"])
Entry.objects.extra(select={'new_id': "select id from tb where id > %s"}, select_params=(1,), order_by=['-nid'])

reverse(self):

# 倒序
 models.UserInfo.objects.all().order_by('-nid').reverse()
# 注:如果存在order_by,reverse则是倒序,如果多个排序则一一倒序

下面两个 取到的是对象,并且注意 取到的对象可以 获取其他字段(这样会再去查找该字段降低性能

defer(self, *fields):

models.UserInfo.objects.defer('username','id')
或
models.UserInfo.objects.filter(...).defer('username','id')
# 映射中排除某列数据

only(self, *fields):

# 仅取某个表中的数据
models.UserInfo.objects.only('username','id')
或
models.UserInfo.objects.filter(...).only('username','id')

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

Python 相关文章推荐
Python实现定时精度可调节的定时器
Apr 15 Python
Python列表解析配合if else的方法
Jun 23 Python
利用Python对文件夹下图片数据进行批量改名的代码实例
Feb 21 Python
python开发游戏的前期准备
May 05 Python
PyQt5 QTable插入图片并动态更新的实例
Jun 18 Python
使用python实现kNN分类算法
Oct 16 Python
Python字符编码转码之GBK,UTF8互转
Feb 09 Python
解决pycharm中opencv-python导入cv2后无法自动补全的问题(不用作任何文件上的修改)
Mar 05 Python
GDAL 矢量属性数据修改方式(python)
Mar 10 Python
在pycharm中文件取消用 pytest模式打开的操作
Sep 01 Python
python实现图片九宫格分割的示例
Apr 25 Python
Python软件包安装的三种常见方法
Jul 07 Python
Python Requests库基本用法示例
Aug 20 #Python
Django中使用第三方登录的示例代码
Aug 20 #Python
基于Django框架利用Ajax实现点赞功能实例代码
Aug 19 #Python
分析python请求数据
Aug 19 #Python
浅谈django orm 优化
Aug 18 #Python
django连接mysql配置方法总结(推荐)
Aug 18 #Python
python画一个玫瑰和一个爱心
Aug 18 #Python
You might like
PHP--用万网的接口实现域名查询功能
2012/12/13 PHP
解析curl提交GET,POST,Cookie的简单方法
2013/06/29 PHP
PHP5.5和之前的版本empty函数的不同之处
2014/06/13 PHP
PHP数据库连接mysql与mysqli对比分析
2016/01/04 PHP
PHP实现上传多图即时显示与即时删除的方法
2017/05/09 PHP
PHP获取数组中单列值的方法
2017/06/10 PHP
PHP实现打包zip并下载功能
2018/06/12 PHP
JS 中document.URL 和 windows.location.href 的区别
2009/11/11 Javascript
JS+CSS实现滑动切换tab菜单效果
2015/08/25 Javascript
浅谈JS继承_寄生式继承 & 寄生组合式继承
2016/08/16 Javascript
javaScript嗅探执行神器-sniffer.js
2017/02/14 Javascript
H5基于iScroll实现下拉刷新和上拉加载更多
2017/07/18 Javascript
Mint-UI时间组件起始时间问题及时间插件使用
2018/08/20 Javascript
Vue加载组件、动态加载组件的几种方式
2018/08/31 Javascript
vue安装和使用scss及sass与scss的区别详解
2018/10/15 Javascript
javascript/jquery实现点击触发事件的方法分析
2019/11/11 jQuery
jQuery cookie的公共方法封装和使用示例
2020/06/01 jQuery
JavaScript Event Loop相关原理解析
2020/06/10 Javascript
vue项目如何监听localStorage或sessionStorage的变化
2021/01/04 Vue.js
Python学习之asyncore模块用法实例教程
2014/09/29 Python
Python读写文件方法总结
2015/06/09 Python
python获得文件创建时间和修改时间的方法
2015/06/30 Python
详解使用 pyenv 管理多个版本 python 环境
2017/10/19 Python
python Celery定时任务的示例
2018/03/13 Python
Python 多线程不加锁分块读取文件的方法
2018/12/11 Python
Python实现连接MySql数据库及增删改查操作详解
2019/04/16 Python
Python+OpenCV+pyQt5录制双目摄像头视频的实例
2019/06/28 Python
Window10下python3.7 安装与卸载教程图解
2019/09/30 Python
Python程序暂停的正常处理方法
2019/11/07 Python
用Python画小女孩放风筝的示例
2019/11/23 Python
python使用scapy模块实现ARP扫描的过程
2021/01/21 Python
岗位职责定义及内容
2013/11/08 职场文书
装修协议书范本
2014/04/21 职场文书
预备党员群众路线思想汇报2014
2014/10/25 职场文书
市直属机关2016年主题党日活动总结
2016/04/05 职场文书
导游词之金鞭溪风景区
2019/09/12 职场文书