django queryset为什么使用count 而不是使用len方法

    2019年9月21日 18:58   118 人阅读  0 条评论   编辑

在Django中,假设我要遍历并打印结果的QuerySet,那么对对象进行计数的最佳选择是什么? len(qs)或qs.count()?是len()方法块,还是count()速度更快?

在len()和count()之间进行选择取决于情况,本文深入讲解len()和count()如何正确使用:

  1. (核心)如果你只想知道元素的数量且不打算以任何方式处理QuerySet时,使用count()是首选

    queryset.count() 等同于sql执行select count(*)  some_table查询,所有计算都是RDBMS(数据端)进行,Python只需要以固定成本O(1)获取结果。

    len(queryset) 这将执行select * from some_table查询,获取整个表O(N),并且需要额为的O(N)内存来存储数据,这是比较麻烦事情。

  2.  当你需要使用QuerySet时,最好使用len(),这样不需要count() 额外再次访问数据库。

len(queryset) # 提取所有数据-无需支付额外费用-仍将在for循环中提取数据

for obj in queryset: # len()已获取数据-使用缓存
    pass

Count

queryset.count() # 这将执行额外的数据库查询-len()没有

for obj in queryset: # 获取数据
    pass

    3.恢复第二种情况(当已经获取查询集时):

for obj in queryset: # 迭代获取数据
    len(queryset) # 使用已经缓存的数据 - O(1) 没有额外开销
    queryset.count() # 使用缓存 - O(1) 没有额外的数据库查询

len(queryset) # 一样 O(1)
queryset.count() # 一样,没有查询 O(1)

QuerySet源码:

class QuerySet(object):

    def __init__(self, model=None, query=None, using=None, hints=None):
        # (...)
        self._result_cache = None

    def __len__(self):
        self._fetch_all()
        return len(self._result_cache)

    def _fetch_all(self):
        if self._result_cache is None:
            self._result_cache = list(self.iterator())
        if self._prefetch_related_lookups and not self._prefetch_done:
            self._prefetch_related_objects()

    def count(self):
        if self._result_cache is not None:
            return len(self._result_cache)

        return self.query.get_count(using=self.db)

querySet文档:

https://docs.djangoproject.com/en/2.2/ref/models/querysets/

本文地址:http://www.chenxm.cc/article/911.html
版权声明: 本文为原创文章,版权归  陈新明  所有,欢迎分享本文,转载请保留出处!
PREVIOUS: django 如何找到两个查询集(querySet)的并集?
NEXT: selenium 通过文字定位元素
 相关文章  关键词:

 发表评论

还没有留言,还不快点抢沙发?