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. 201521123062《Java程序设计》第1周学习总结

    1.本章学习总结 认识Java平台运行环境,运行软件 初步认识JDK,JRE,JVM基本含义 书面作业 1.为什么java程序可以跨平台运行?执行java程序的步骤是什么? Java平台运行在各平台的 ...

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

    1. 本章学习总结 2. 书面作业 1. 网络基础 1.1 比较ping www.baidu.com与ping cec.jmu.edu.cn,分析返回结果有何不同?为什么会有这样的不同? 1.2 te ...

  3. 201521123074 《Java程序设计》第14周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多数据库相关内容. 2. 书面作业 Q1. MySQL数据库基本操作 建立数据库,将自己的姓名.学号作为一条记录插入.(截图,需出现 ...

  4. 《MySQL必知必会》[03] 表数据的增删改

    1.增:插入数据 INSERT关键字可以插入新的行到数据库表中: 插入完整的行 插入行的一部分 插入多行 插入某些查询的结果 基本的INSERT语句是: INSERT INTO R(A1, A2, . ...

  5. 虚拟WEB目录的映射原理

    一个文件系统目录可以被映射成为多个虚拟WEB目录,虚拟WEB目录名称可以是多级目录结构的形式,tomca按照最长路径匹配原则处理请求的URL 设置WEB站点的根目录: <Host>元素的a ...

  6. jdk版本切换

    安装1.6/1.7/1.8版本的jdk 保存jdk的安装目录下的文件 卸载所有jdk 将jdk各个版本拷贝到一个文件夹下 配置环境变量 因为安装之后系统会有注册表之类的文件,单纯的修改环境是不会修改成 ...

  7. Java线程池带图详解

    线程池作为Java中一个重要的知识点,看了很多文章,在此以Java自带的线程池为例,记录分析一下.本文参考了Java并发编程:线程池的使用.Java线程池---addWorker方法解析.线程池.Th ...

  8. Codeforce E. Fire

    E. Fire time limit per test 2 seconds memory limit per test 256 megabytes input standard input outpu ...

  9. TCP/IP(二)物理层详解

    前言 在前面说了一下,计算机网络的大概内容,没有去深刻的去了解它,这篇文章给大家分享一下物理层! 我们知道ISO模型是七层,TCP/IP模型是五层,而tcp/ip协议只将七层概括为4层,我们将学习其中 ...

  10. ASP.NET Core中如何调整HTTP请求大小的几种方式

    一.前言 一般的情况下,我们都无需调用HTTP请求的大小,只有在上传一些大文件,或者使用HTTP协议写入较大的值时(如调用WebService)才可能会调用HTTP最大请求值. 在ASP.NET Co ...