zoukankan      html  css  js  c++  java
  • Django OMR QuerySet的特性/存在意义

     

    QuerySet存在的意义主要在惰性机制和缓存两点

    ---------->惰性机制:

    所谓惰性机制:Publisher.objects.all()或者.filter()等都只是返回了一个QuerySet(查询结果集对象),它并不会马上执行sql,而是当调用QuerySet的时候才执行。

    QuerySet特点:

           <1>  可迭代的

           <2>  可切片【做分页时经常用到】

    复制代码
        #objs=models.Book.objects.all()#[obj1,obj2,ob3...]
    
        #QuerySet:   可迭代
    
        # for obj in objs:#每一obj就是一个行对象
        #     print("obj:",obj)
        # QuerySet:  可切片
    
        # print(objs[1])
        # print(objs[1:4])
        # print(objs[::-1])

    复制代码
        #objs=models.Book.objects.all()#[obj1,obj2,ob3...]
    
        #QuerySet:   可迭代
    
        # for obj in objs:#每一obj就是一个行对象
        #     print("obj:",obj)
        # QuerySet:  可切片
    
        # print(objs[1])
        # print(objs[1:4])
        # print(objs[::-1])
    复制代码
    复制代码

    QuerySet的高效使用:

    1.   惰性的
    2.   调用时执行sql【调用--》for循环,做if条件等使用此变量】,放入缓存
    3.   具有cache
    4.   if判断会执行整个queryset,并放入缓存
    5.   iterator()方法,禁止缓存,减少缓存的使用,但增加了数据库查询
    复制代码

    <1>Django的queryset是惰性的

    Django的queryset对应于数据库的若干记录(row),通过可选的查询来过滤。例如,下面的代码会得
    到数据库中名字为‘Dave’的所有的人:person_set = Person.objects.filter(first_name="Dave")
    上面的代码并没有运行任何的数据库查询。你可以使用person_set,给它加上一些过滤条件,或者将它传给某个函数,
    这些操作都不会发送给数据库。这是对的,因为数据库查询是显著影响web应用性能的因素之一。

    <2>要真正从数据库获得数据,你可以遍历queryset或者使用if queryset,总之你用到数据时就会执行sql.
    为了验证这些,需要在settings里加入 LOGGING(验证方式)
    obj=models.Book.objects.filter(id=3)
    # for i in obj:
    # print(i)

    # if obj:
    # print("ok")

    <3>queryset是具有cache的
    当你遍历queryset时,所有匹配的记录会从数据库获取,然后转换成Django的model。这被称为执行
    (evaluation).这些model会保存在queryset内置的cache中,这样如果你再次遍历这个queryset,
    你不需要重复运行通用的查询。
    obj=models.Book.objects.filter(id=3)

    # for i in obj:
    # print(i)
    ## models.Book.objects.filter(id=3).update(title="GO")
    ## obj_new=models.Book.objects.filter(id=3)
    # for i in obj:
    # print(i) #LOGGING只会打印一次

    <4>
    简单的使用if语句进行判断也会完全执行整个queryset并且把数据放入cache,虽然你并不需要这些
    数据!为了避免这个,可以用exists()方法来检查是否有数据:

    obj = Book.objects.filter(id=4)
    # exists()的检查可以避免数据放入queryset的cache。
    if obj.exists():
    print("hello world!")

    <5>当queryset非常巨大时,cache会成为问题

    处理成千上万的记录时,将它们一次装入内存是很浪费的。更糟糕的是,巨大的queryset可能会锁住系统
    进程,让你的程序濒临崩溃。要避免在遍历数据的同时产生queryset cache,可以使用iterator()方法
    来获取数据,处理完数据就将其丢弃。
    objs = Book.objects.all().iterator()
    # iterator()可以一次只从数据库获取少量数据,这样可以节省内存
    for obj in objs:
    print(obj.name)
    #BUT,再次遍历没有打印,因为迭代器已经在上一次遍历(next)到最后一次了,没得遍历了
    for obj in objs:
    print(obj.name)

    #当然,使用iterator()方法来防止生成cache,意味着遍历同一个queryset时会重复执行查询。所以使
    #用iterator()的时候要当心,确保你的代码在操作一个大的queryset时没有重复执行查询

    总结:
    queryset的cache是用于减少程序对数据库的查询,在通常的使用下会保证只有在需要的时候才会查询数据库。
    使用exists()和iterator()方法可以优化程序对内存的使用。不过,由于它们并不会生成queryset cache,可能
    造成额外的数据库查询


    复制代码
    <1>Django的queryset是惰性的
    
         Django的queryset对应于数据库的若干记录(row),通过可选的查询来过滤。例如,下面的代码会得
         到数据库中名字为‘Dave’的所有的人:person_set = Person.objects.filter(first_name="Dave")
         上面的代码并没有运行任何的数据库查询。你可以使用person_set,给它加上一些过滤条件,或者将它传给某个函数,
         这些操作都不会发送给数据库。这是对的,因为数据库查询是显著影响web应用性能的因素之一。
    
    <2>要真正从数据库获得数据,你可以遍历queryset或者使用if queryset,总之你用到数据时就会执行sql.
       为了验证这些,需要在settings里加入 LOGGING(验证方式)
            obj=models.Book.objects.filter(id=3)
            # for i in obj:
            #     print(i)
    
            # if obj:
            #     print("ok")
    
    <3>queryset是具有cache的
         当你遍历queryset时,所有匹配的记录会从数据库获取,然后转换成Django的model。这被称为执行
        (evaluation).这些model会保存在queryset内置的cache中,这样如果你再次遍历这个queryset,
         你不需要重复运行通用的查询。
            obj=models.Book.objects.filter(id=3)
    
            # for i in obj:
            #     print(i)
                              ## models.Book.objects.filter(id=3).update(title="GO")
                              ## obj_new=models.Book.objects.filter(id=3)
            # for i in obj:
            #     print(i)   #LOGGING只会打印一次
    
    <4>
         简单的使用if语句进行判断也会完全执行整个queryset并且把数据放入cache,虽然你并不需要这些
         数据!为了避免这个,可以用exists()方法来检查是否有数据:
    
                obj = Book.objects.filter(id=4)
                #  exists()的检查可以避免数据放入queryset的cache。
                if obj.exists():
                    print("hello world!")
    
    <5>当queryset非常巨大时,cache会成为问题
    
         处理成千上万的记录时,将它们一次装入内存是很浪费的。更糟糕的是,巨大的queryset可能会锁住系统
         进程,让你的程序濒临崩溃。要避免在遍历数据的同时产生queryset cache,可以使用iterator()方法
         来获取数据,处理完数据就将其丢弃。
            objs = Book.objects.all().iterator()
            # iterator()可以一次只从数据库获取少量数据,这样可以节省内存
            for obj in objs:
                print(obj.name)
            #BUT,再次遍历没有打印,因为迭代器已经在上一次遍历(next)到最后一次了,没得遍历了
            for obj in objs:
                print(obj.name)
    
         #当然,使用iterator()方法来防止生成cache,意味着遍历同一个queryset时会重复执行查询。所以使
         #用iterator()的时候要当心,确保你的代码在操作一个大的queryset时没有重复执行查询
    
    总结:
        queryset的cache是用于减少程序对数据库的查询,在通常的使用下会保证只有在需要的时候才会查询数据库。
    使用exists()和iterator()方法可以优化程序对内存的使用。不过,由于它们并不会生成queryset cache,可能
    会造成额外的数据库查询。
    复制代码
     
     
     
  • 相关阅读:
    ORACLE学习-1.过滤和排序
    Java-net.sf.json.JSONException: java.lang.reflect.InvocationTargetException处理方法之一
    ORACLE
    java日常-com.alibaba.fastjson快速处理json字符串转成list类型
    java日常-List、Map初始值
    javaScript中获取时间
    获取select的option值及其文本
    java日常-通过年月,获取到月的第一天和最后一天
    sybase powerdesigner 16.5注册码
    05-Docker私有仓库
  • 原文地址:https://www.cnblogs.com/rain-chenwei/p/9685486.html
Copyright © 2011-2022 走看看