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. 201521123109《java程序设计》第三周学习总结

    1. 本周学习总结 初学面向对象,会学习到很多碎片化的概念与知识.尝试学会使用思维导图将这些碎片化的概念.知识组织起来.请使用纸笔或者下面的工具画出本周学习到的知识点.截图或者拍照上传. 2. 书面作 ...

  2. Java课程设计 学生基本信息管理系统 团队博客

    学生基本信息管理系统团队博客 项目git地址 https://git.oschina.net/Java_goddess/kechengsheji 项目git提交记录截图 项目功能架构图与主要功能流程图 ...

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

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

  4. 201521123070 《JAVA程序设计》第10周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常与多线程相关内容. 2. 书面作业 本次PTA作业题集异常.多线程 Q1. finally 题目4-2 1.1 截图你的提交结果 ...

  5. logback:logback和slf4j中的:appender、logger、encoder、layout

    (1)appender 1.appender标签是logback配置文件中重要的组件之一.在logback配置文件中使用appender标签进行定义.可 以包含0个或多个appender标签. 2.a ...

  6. Eclipse rap 富客户端开发总结(7) : 如何修改rap的样式

    1. Rap样式原理  Rap的界面样式目前是以css来配置的,程序启动后加载相应的css配置文件再对组件进行样式设置,界面上的所有组件 Label button composit等的样式最开始都是通 ...

  7. java进程/线程;堆和栈;多线程

    一.进程和线程 进程:在内存中运行的应用程序,一个exe是一个进程. 如:ps -exf  可以查看各个应用的进程,其中ppid为父进程: ps aux | egrep '(cron|syslog)' ...

  8. 初学者---AngularJS详解

    AngularJS 简介 AngularJs是一个用于设计动态web应用的结构框架.首先,它是一个框架,不是类库,提供一整套方案用于设计web应用.它不仅仅是一个javascript框架,因为它的核心 ...

  9. open和opener使用說明

    父網頁:window.open("article.html")子網頁:var dialoginfo=$('#dialogdata',window.opener.document); ...

  10. PyTorch教程之Training a classifier

    我们已经了解了如何定义神经网络,计算损失并对网络的权重进行更新. 接下来的问题就是: 一.What about data? 通常处理图像.文本.音频或视频数据时,可以使用标准的python包将数据加载 ...