zoukankan      html  css  js  c++  java
  • queryset特性和queryset优化

        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
    可能会造成额外的数据库查询。
  • 相关阅读:
    团队冲刺阶段二(八)
    团队项目事后诸葛亮会议
    团队冲刺阶段二(七)
    团队冲刺阶段二(六)
    团队冲刺阶段二(五)
    团队冲刺阶段二(四)
    HTML5 CSS3
    浮动和渐变色,定位position,元素的层叠顺序
    css盒模型。边框和内外边距
    标签分类与元素转换
  • 原文地址:https://www.cnblogs.com/zgf-666/p/9198546.html
Copyright © 2011-2022 走看看