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

    本周学习总结 书面作业 代码阅读 public class Test1 { private int i = 1;//这行不能修改 private static int j = 2; public st ...

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

    一.学习总结 学习了运算符的基本使用方法: 学习了string这个特殊的类型: 学习了数组的使用方法. 二.书面作业 1.使用Eclipse关联jdk源代码,并查看String对象的源代码(截图)? ...

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

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

  4. 201521123057 《Java程序设计》第10周学习总结

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

  5. 201521123092《java程序设计》第九周学习总结

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

  6. select应用于read函数 超时非阻塞方式

    /* * "Timed" read - timout specifies the # of seconds to wait before * giving up (5th argu ...

  7. LuoguP1196_银河英雄传说_KEY

    银河英雄传说 题目描述 公元5801年,地球居民迁移至金牛座α第二行星,在那里发表银河联邦创立宣言,同年改元为宇宙历元年,并开始向银河系深处拓展. 宇宙历799年,银河系的两大军事集团在巴米利恩星域爆 ...

  8. iOS 多人共享开发证书

    当多人开发时,如果已经申请了几个开发者证书和发布者证书,苹果就不允许再创建了,页面添加的地方被灰化了,所以不可能每个人都建一个开发证书,这时候需要共用一个证书了.(其实一般在我们的证书界面中应该只有一 ...

  9. 实例讲解webpack的基本使用第一篇

    更新文章不容易,尤其是更新高质量的文章更加不易,因此为了节约时间,闲话就不多说了.关于webpack的介绍,webpack是用来干嘛的,这些基础概念性的东西,就不在此赘述,下面直接开始正题. webp ...

  10. 每周分享之 二 http协议(2)

    本次分享http协议,共分为三部分,这是第二部分,主要讲解请求与响应的字段,以及状态码. 以http/1.1版本的一个完整的请求与响应作为例子 http请求信息由三部分组成 1.请求方法(GET/PO ...