queryset特性和queryset优化

摘要:
更糟糕的是,庞大的查询集可能会锁定系统进程,使程序接近崩溃。为了避免在遍历数据时生成querysetcache,可以使用迭代器()方法获取数据。处理完数据后,可以丢弃它queryset=Book。物体。all()iter=queryset。迭代器()。一次只能从数据库中获取少量数据,这样可以节省内存。print<class‘generator‘>generator forobfiniter:print在不打印的情况下再次遍历,因为迭代器已经遍历了最后一次,我们不必遍历forobfinite:printqueryset缓存用于减少程序对数据库的查询。使用exists()和迭代器()方法可以优化程序对内存的使用。但是,它们可能会导致额外的数据库查询,因为它们不会生成querysetcache。
    queryset特点    

1.可以切片使用:不支持负的索引

book_list=models.Book.objects.all()
print(book_list)   #<QuerySet [<Book: python>, <Book: go>]>
book_list[0:1]   #<QuerySet [<Book: python>]>

2.可迭代

book_list=models.Book.objects.all()
 for obj in book_list: 
    print(obj.title,obj.price)

3.惰性查询:

创建查询集不会带来任何数据库的访问,对这个查询集求值时,才会真正运行这个查询
query = Person.objects.filter(first_name="Dave")
queryset=Book.objects.all() 此时只是创建了查询集query,并没有运行,因此并没有执行相应的sql语句
要真正从数据库获得数据,需要遍历queryset:
for article in queryset:
    print(article.title)    # hits database
print(queryset) # hits database 对queryset进行了查询,sql语句执行

4.缓存机制:

当遍历queryset时,所有匹配的记录会从数据库获取,然后转换成Django的model。这些model会保存在queryset内置的cache中,
如果再次遍历这个queryset,将直接使用缓存中的结果
执行下列代码,queryset执行两次,但sql只执行了一次
queryset=Book.objects.all()
for obj in queryset:
    print(obj.title)
for obj1 in queryset:
    print(obj1.title)
使用同一查询集,sql只执行一次
queryResult=models.Book.objects.all()
print([a.title for a in queryResult])
print([a.create_time for a in queryResult])
执行下列代码,queryset执行两次,sql执行了两次
for obj in Book.objects.all():
        print(obj.title)
for obj1 in Book.objects.all():
    print(obj1.title)
重复获取查询集对象中一个特定的索引需要每次都查询数据库
queryset = Entry.objects.all()
print queryset[5] # Queries the database
print queryset[5] # Queries the database again
       queryset优化     

exists()与iterator()方法

queryset的cache最有用的地方是可以有效的测试queryset是否包含数据,只有有数据时才会去遍历

1.if语句会触发queryset的执行

book_list=models.Book.objects.all()
if book_list:  #执行sql,查询数据库
    for obj in queryset:
    print(obj.title)
2.当需求只是否判断数据是否存在,而不需要遍历所有的数据。这种情况,简单的使用if语句进行判断也会完全执行整个queryset
并且把数据放入cache
book_list=models.Book.objects.all() 
if book_list: #我们并不需要所有的数据,但是ORM仍然会获取所有记录!
  print(
"ok") 用exists()方法来检查是否有数据:
book_list
=models.Book.objects.all()   
  if book_list.exists(): # 没有数据从数据库获取,从而节省了带宽和内存。只取第一条内容 print("ok")
3.处理成千上万的记录时,将它们一次装入内存是很浪费的。更糟糕的是,巨大的queryset可能会锁住系统进程,让你的程序濒临崩溃。
要避免在遍历数据的同时产生queryset cache,可以使用iterator()方法来获取数据,处理完数据就将其丢弃
queryset = Book.objects.all()
iter=queryset.iterator() 可以一次只从数据库获取少量数据,这样可以节省内存
print(type(iter))   <class 'generator'> 生成器
for obj in iter:
    print(obj.title)
再次遍历没有打印,因为迭代器已经在上一次遍历(next)到最后一次了,没得遍历了
for obj in iter:
    print(obj.title)
queryset的cache是用于减少程序对数据库的查询, 使用exists()和iterator()方法可以优化程序对内存的使用。不过,由于它们并不会生成queryset cache
可能会造成额外的数据库查询。

免责声明:文章转载自《queryset特性和queryset优化》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇CBV和APIView流程javascript的数据类型,运算符和流程控制下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

数据结构中用邻接矩阵方式储存图,广度优先,深度优先遍历

数据结构中用邻接矩阵方式储存图,广度优先,深度优先遍历 - python - ITeye技术网站 数据结构中用邻接矩阵方式储存图,广度优先,深度优先遍历 博客分类:c 语言 数据结构J# 以下是作业,用它用实现用邻接矩阵的方式来进行广度优先和深度优先的遍历。 代码比较简单,用了两个小时来写出来。 /**用邻接矩阵的方式来储存图,用广度优先...

springmvc返回数据库不为空的数据的方法(或JSONObject过滤null字段的方法)

1. 过滤整个项目中JSONObject对象里的null字段:找到你的项目中的SpringMVC-Servlet.xml配置文件,找到配置<mvc:annotation-driven />的地方,添加如下配置: 2.过滤指定对象中的null字段:在对象的bean的头部也就是你的实体类字段添加@JsonSerialize注解: @JsonSer...

Mysql索引分类

在绝大多数情况下,Mysql索引都是基于B+树的,而索引可以提高数据查询的效率。但是Mysql是如何利用B+树进行查询的呢?索引的作用只是提高查询效率吗? Mysql中的B+Tree索引 假设有一张教师表,里面有教师编号、名字、学科、薪资四个字段。 当你执行下面这条创建索引的sql语句时:create index id_name on teacher(nam...

如何区分oracle服务器、oracle客户端、plsql?

大家在安装oracle数据库的时候,是不是有很多区分不清的概念,以至于束手无策呢?现在有一个问题,就是怎么区分oracle服务器、oracle客户端、plsql三者的概念?我想,新手在安装的时候可能会遇到这个问题而分不清。 1.安装了Oracle服务器后,可以在自己本地电脑上随便新建数据库,所有操作都可以执行。 2.安装了Oracle服务...

带参数的存储过程

带参数的存储过程 创建带参数的sql存储过程:创建带参数的存储过程首先要在存储过程中声明该参数,每个存储过程参数都必须用惟一的名称进行定义。与标准的Transact-SQL变量相同,参数名必须以@为前缀,创建带参数的存储过程创建带参数的存储过程首先要在存储过程中声明该参数,每个存储过程参数都必须用惟一的名称进行定义。与标准的Transact-SQL变...

Django2.2使用mysql数据库pymysql版本不匹配问题的解决过程与总结

前置条件 django版本:2.2.1 python版本:3.6.6 mysql版本:mysql-community8.0.15 问题 在搭建django项目,配置mysql数据库时遇到无法迁移数据库的问题,错误信息如下图: 问题分析过程 由错误信息,可大致看出是一个叫mysqlclient的包版本不匹配导致的问题。 搜索引擎检索相关错误,得知:pytho...