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 相关文章推荐
Pyhton中防止SQL注入的方法
Feb 05 Python
Python如何实现文本转语音
Aug 08 Python
Python 性能优化技巧总结
Nov 01 Python
Python MySQLdb 使用utf-8 编码插入中文数据问题
Mar 13 Python
Python中按值来获取指定的键
Mar 04 Python
Python动态赋值的陷阱知识点总结
Mar 17 Python
python网络应用开发知识点浅析
May 28 Python
python 下 CMake 安装配置 OPENCV 4.1.1的方法
Sep 30 Python
python:批量统计xml中各类目标的数量案例
Mar 10 Python
Python格式化输出--%s,%d,%f的代码解析
Apr 29 Python
Python字符串格式化常用手段及注意事项
Jun 17 Python
Anaconda+spyder+pycharm的pytorch配置详解(GPU)
Oct 18 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 多进程 解决难题
2009/06/22 PHP
Yii2框架类自动加载机制实例分析
2018/05/02 PHP
javascript 广告后加载,加载完页面再加载广告
2010/11/25 Javascript
in.js 一个轻量级的JavaScript颗粒化模块加载和依赖关系管理解决方案
2011/07/26 Javascript
如何使用jquery控制CSS样式,并且取消Css样式(如背景色,有实例)
2013/07/09 Javascript
网站内容禁止复制和粘贴、另存为的js代码
2014/02/26 Javascript
javascript自定义的addClass()方法
2014/05/28 Javascript
jQuery中的jQuery()方法用法分析
2014/12/27 Javascript
JS Ajax请求如何防止重复提交
2016/06/13 Javascript
深入分析node.js的异步API和其局限性
2016/09/05 Javascript
jQuery动态生成Bootstrap表格
2016/11/01 Javascript
jQuery Mobile漏洞会有跨站脚本攻击风险
2017/02/12 Javascript
JS原生轮播图的简单实现(推荐)
2017/07/22 Javascript
Angular 4.0学习教程之架构详解
2017/09/12 Javascript
layer子层给父层页面元素赋值,以达到向父层页面传值的效果实例
2017/09/22 Javascript
微信小程序开发之好友列表字母列表跳转对应位置
2017/09/26 Javascript
Vue2(三)实现子菜单展开收缩,带动画效果实现方法
2019/04/28 Javascript
解决layer.open后laydate失效的问题
2019/09/06 Javascript
详解webpack-dev-middleware 源码解读
2020/03/23 Javascript
python实现数值积分的Simpson方法实例分析
2015/06/05 Python
Python实现简单的文件传输与MySQL备份的脚本分享
2016/01/03 Python
详解python基础之while循环及if判断
2017/08/24 Python
详解Django rest_framework实现RESTful API
2018/05/24 Python
在python中实现同行输入/接收多个数据的示例
2019/07/20 Python
澳大利亚领先的睡衣品牌:Peter Alexander
2016/08/16 全球购物
英国最受欢迎的平价女士时装零售商:Roman Originals
2019/11/02 全球购物
database面试题
2013/03/28 面试题
EJB3.1都有哪些改进
2012/11/17 面试题
数控机械专业个人的自我评价
2014/01/02 职场文书
学生拾金不昧表扬信
2014/01/21 职场文书
大学军训感言200字
2014/02/26 职场文书
推荐信格式要求
2014/05/09 职场文书
学习退步检讨书
2014/09/28 职场文书
幼儿园迎新生欢迎词
2015/09/30 职场文书
小学数学继续教育研修日志
2015/11/13 职场文书
MySql统计函数COUNT的具体使用详解
2022/08/14 MySQL