django_orm查询性能优化方法
作者:dragonliu 发布时间:2021-03-01 20:30:19
标签:django,orm,查询,优化
查询操作和性能优化
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')
来源:https://www.cnblogs.com/liujiliang/p/9171675.html


猜你喜欢
- 良好的编程习惯是每个程序员都应该具备的工作素质,在我的软件生涯中屡屡发现一些程序员的身上总有这样或者那样的坏毛病。这些毛病在一些从业时间不是
- Ursina是一个3D引擎,初步使用方法,见文章:详解Python 3D引擎Ursina如何绘制立体图形了解完Ursina的初步用
- 使用Python读取解析xmind文件,一键统计测试用例数量。问题:做测试的朋友们经常会用到xmind这个工具来梳理测试点或写测试用例,但是
- 简单试用了一下IE8后,今天相对有时间点,对IE8、IE7、IE6、Firefox2.0.0.12做了简单的一些CSS HACK测
- 目录一、前端控制1、在router.js文件(把静态路由和动态路由分别写在router.js)2、store/permission.js(在
- python图片生成视频MP4import osimport cv2# 要被合成的多张图片所在文件夹# 路径分隔符最好使用“/”,而不是“\
- 在matplotlib下,一个Figure对象可以包含多个子图(Axes),可以使用subplot()快速绘制,其调用形式如下:subplo
- a. 如果欲使用gb2312编码,那么php要输出头:header(“Content-Type: text/html; charset=gb
- 1、问题:安装VSCode后打开,发现显示的语言为英文,想显示为中文?2、解决方法:2.1、快捷键CTRL+SHIFT+P,找到如下设置Co
- 基础知识介绍以SQL Server的数据库管理工具SSMS(SQL Server Management Studio)为平台进行操作。SQL
- 实现网页的键盘输入操作from selenium.webdriver.common.keys import Keys * 页有时需要将鼠标
- MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下公司。MySQL 最流行的关系型数据库管
- 在ubuntu论坛上看到一个抓取网页里的图片数据的帖子,于是就想着用GO语言来试下。那么先安装一个运行环境吧。以下安装方式在32位和64位的
- 建表,主键自增create table aaa(id bigint identity(1,1) not null PRIMARY key,n
- 一、背景我们在进行代码调试时,通常使用两种方式。print 输出调试的内容或者标识通过断点调试debug但是我想知道代码的中间的每一行程序运
- 前言我们在工作中的时候,会有这种需求:用户上传一个格式固定excel表格到网站上,然后程序负债解析内容并进行处理。我最近在工作中就遇到了,所
- 所谓异常指的是程序的执行出现了非预期行为,就好比现实中的做一件事过程中总会出现一些意外的事。异常的处理是跨越编程语言的,和具体的编程细节相比
- 具体代码如下所示:#!/usr/bin/python# coding=utf-8from ftplib import FTPimport t
- django模板使用media文件夹,想要在前端通过{{ MEDIA_URL }}无法显示图片,没有取到Media_url的值解决办法:TE
- 本文通过Docker Compose来创建mysql容器在linux服务器上创建文件,用于管理容器 mkdir docker-mysql c