微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

在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/

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐