Django数据库操作性能相关

案例:

现在我们的数据库中有两张表如下:

1.职员表:

class UserInfo(models.Model):
name = models.CharField(max_length=32)
pwd = models.CharField(max_length=64)
ut = models.ForeignKey(to='UserType',to_field='id',null=True)

2.职位表:

class UserType(models.Model):
Job = models.CharField(max_length=32)

需求:

1.我们现在将所有的职员和对应的职位输入出来:

def login(request):

    user_list = models.UserInfo.objects.all()

	for row in user_list:
print(row.name,row.pwd,row.ut.Job) return HttpResponse("OK")

上述代码中row.name和row.pwd是单表操作而row.ut.job关系到了连表操作。当代码执行到for循环时下面每一次循环都经过了一次数据库,即带着ForeignKey的ut去UserType表中读取职位信息,过程中循环5次就进入数据库5次,所以随着数据库的数据的增加其性能会越来越低。

所以我们需要优化:

优化代码:

def login(request):

    user_list2=models.UserInfo.objects.values("name","pwd","ut__Job")
print(user_list2.query) print(user_list.query)
for row in user_list2:
print(row["name"],row["pwd"],row["ut__Job"]) return HttpResponse("OK")

通过values可以一次性将两张表得数据都取出来在通过for循环输出对应的数据,该过程只查询一次数据库,性能比之前强很多。

但是values的取值方式只是values值,更多的时候我们需要的是一个个的对象,所以下面我们可以使用这种方式:

def login(request):

    user_list = models.UserInfo.objects.all().select_related('ut')  #该处的"ut"是该表的ForeignKey的字段。

    print(user_list.query)  #查看MySQL查询语句

这是MySQL的原生查询语句:

SELECT "xingneng_userinfo"."id", "xingneng_userinfo"."name", "xingneng_userinfo"."pwd", "xingneng_userinfo"."ut_id", "xingneng_usertype"."id", "xingneng_usertype"."Job" FROM "xingneng_userinfo" LEFT OUTER JOIN "xingneng_usertype" ON ("xingneng_userinfo"."ut_id" = "xingneng_usertype"."id")

综上所述的查询我们统称为主动连表查询,其缺点就性能低

	select_related,主动连表查询【FK】

		user_list = models.UserInfo.objects.all().select_related('FK字段')
for row in user_list:
# 只去取当前表数据和FK表关联字段 user_list = models.UserInfo.objects.values(...)
for row in user_list:
# 只去取当前表数据和FK表关联字段

prefetch_related方法

def login(request):

    user_list = models.UserInfo.objects.all().prefetch_related('ut')

    for row in user_list:
print(row.name,row.pwd,row.ut.Job)
return HttpResponse("OK")

上述的代码整个执行流程:

  • 查询职员表models.UserInfo.objects.all

  • 把用户表中所有的ut_id拿到,用户类型ID[1,2,3]

  • select * from UserType where id in [1,2,3]

这里需要理解的是当职员表中用1000个职员,但是职位类型却只有三种[1,2,3],那么prefetch_related方法就只会将这三个类型的职位读取出来而不会去循环一千次取一千次。这里没有练表而且只分别去两个表中读取对应的数据,即只执行两次数据库查询。

only方法(只取某个字段)

def login(request):

    user_list = models.UserInfo.objects.all().only('name')

    for row in user_list:
print(row.name)
return HttpResponse("OK")

only后的字段表示在查询数据库时只查该字段,且该字段的查询结果也是一个个的对象,相比values更优些。需要注意当你查询的字段不是only中的字段其性能会很差

defer方法(排除某个字段)

def login(request):

    user_list = models.UserInfo.objects.all().defer('name')

    for row in user_list:
print(row.pwd)
return HttpResponse("OK")

defer方法刚好与only方法相反,表示只查与defer后的字段以外的字段。需要注意当你查询的字段是你排除的字段,查询的性能会很低

Django数据库操作性能相关的更多相关文章

  1. django数据库迁移相关【sqlite3迁移到MySQL】(django2.0.3测试通过)

    前言 项目部署到服务器之后,用的数据库还是sqlite3. 发现一些问题,sqlite3是小巧,但是服务器上查看数据库比较费劲,不能直观看到数据.可是我们经常需要即时.直观查看数据,这就用到MySQL ...

  2. Python之路【第十九章】:Django 数据库对象关系映射

    Django ORM基本配置 到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞: 创建数据库,设计表结构和字段 使用 MySQLdb 来连接数据库,并编写数据访问层代码 业务逻辑层去 ...

  3. Django ORM那些相关操作zi

    Django ORM那些相关操作   一般操作 看专业的官网文档,做专业的程序员! 必知必会13条 <1> all(): 查询所有结果 <2> filter(**kwargs) ...

  4. 记Django数据库迁移过程中遇到的一些问题

    首先描述一下问题,Django 数据库使用的mysql, 然后开始没注意,没建一个default库,就把第一个数据库当成默认的了,结果Django的admin相关的那些表,都自动生成到这个库里了,现在 ...

  5. Django ORM 那些相关操作

    Django ORM 那些相关操作 一般操作 必知必会13条 <> all(): #查询所有的结果 <> filter(**kwargs) # 它包含了与所给筛选条件相匹配的对 ...

  6. django数据库事务

    数据库原子操作 举个例子: 一个消费者在一个商户里刷信用卡消费,交易正常时,银行在消费者的账户里减去相应的款项,在商户的帐户加上相应的款项.但是如果银行从消费者的账户里扣完钱之后,还未在商户的帐户里加 ...

  7. day53_9_17 django数据库表关联,路由和视图

    一.数据库的关系建立. 在原生的数据库语句中,建立表与表之间的联系,就是添加一个字段,将联系的表的id值添加到该字段中. django所作的也就是这些. 以图书管理系统为例,图书管理系统有四张表:书籍 ...

  8. Django 数据库查询集合(多对多)

    Django 数据库查询集合(双下划线连表操作) 目录: 1.Django环境搭建 2.数据库建表 3.写入数据 4.查询语句 Django环境搭建 1.安装django pip install dj ...

  9. 6月15日 python学习总结 Django模板语言相关内容

    Django模板语言相关内容   Django模板系统 官方文档 常用语法 只需要记两种特殊符号: {{  }}和 {% %} 变量相关的用{{}},逻辑相关的用{%%}. 变量 {{ 变量名 }} ...

随机推荐

  1. 201521123072《java程序设计》第十四周学习总结

    201521123072<java程序设计>第十四周学习总结 1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多数据库相关内容. 2. 书面作业 1. MySQL数据库 ...

  2. 201521123067 《Java程序设计》第13周学习总结

    201521123067 <Java程序设计>第13周学习总结 1. 本周学习总结 以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容. 2. 书面作业 Q1. 网络基 ...

  3. 201521123059 《Java程序设计》第十二周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多流与文件相关内容. 2. 书面作业 将Student对象(属性:int id, String name,int age,doubl ...

  4. 201521123119 《Java程序设计》第13周学习总结

    1. 本周学习总结 Q以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容. 2. 书面作业 Q1. 网络基础 Q1.1 比较ping www.baidu.com与ping cec. ...

  5. 201521123015 《Java程序设计》第9周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常相关内容. 2. 书面作业 本次PTA作业题集异常 1.常用异常 题目5-1 1.1 截图你的提交结果(出现学号) 1.2 自己 ...

  6. Nim函数调用的几种形

    Nim函数调用的几种形式 Nim 转载条件:如果你需要转载本文,你需要做到完整转载本文所有的内容,不得删改文内的作者名字与链接.否则拒绝转载. 关于nim的例行介绍: Nim 是一门静态编译型的系统级 ...

  7. Oracle存储过程经典入门

    ok基本就这些介绍

  8. 14.LINUX-platform机制实现驱动层分离(详解)

    版权声明:本文为博主原创文章,未经博主允许不得转载. 本节目标:        学习platform机制,如何实现驱动层分离 1.先来看看我们之前分析输入子系统的分层概念,如下图所示: 如上图所示,分 ...

  9. spring cloud+dotnet core搭建微服务架构:服务发现(二)

    前言 上篇文章实际上只讲了服务治理中的服务注册,服务与服务之间如何调用呢?传统的方式,服务A调用服务B,那么服务A访问的是服务B的负载均衡地址,通过负载均衡来指向到服务B的真实地址,上篇文章已经说了这 ...

  10. java集合系列——List集合之LinkedList介绍(三)

    1. LinkedList的简介 JDK 1.7 LinkedList是基于链表实现的,从源码可以看出是一个双向链表.除了当做链表使用外,它也可以被当作堆栈.队列或双端队列进行操作.不是线程安全的,继 ...