在Django QuerySet上计数vs len
在Django中,鉴于我有一个QuerySet,我将迭代并打印结果,什么是计数对象的最佳select? len(qs)或qs.count()?
(同样,迭代中计数对象不是一个选项)
尽pipeDjango文档build议使用count而不是len : 
注意:如果您想要执行的操作只是确定集合中的logging数,请不要在QuerySets上使用
len()。 使用SQL的SELECT COUNT(*)来处理数据库级别的计数会更有效率,而Django正是出于这个原因提供了一个count()方法。
 既然你正在迭代这个QuerySet, 结果将被caching (除非你使用iterator ),所以最好使用len ,因为这避免了再次敲击数据库,并且还可能检索不同数量的结果 !)。 
 如果你正在使用iterator ,那么我会build议在迭代(而不是使用count)出于同样的原因包括一个计数variables。 
 我认为使用len(qs)在这里更有意义,因为你需要迭代结果。 如果所有你想要做的都打印计数而不是遍历结果, qs.count()是一个更好的select。 
  len(qs)将使用select * from table命中数据库,而qs.count()将使用select count(*) from table命中db。 
 也qs.count()将返回整数,你不能遍历它 
  len()和count()之间的select取决于具体情况,值得深入理解它们如何正确使用它们。 
让我给你提供几个scheme:
- 
(最重要的)当你只想知道元素的数量,而不打算以任何方式处理它们时,使用 count()是至关重要的:DO: queryset.count()– 这将执行单个SELECT COUNT(*) some_table查询,所有的计算都在RDBMS端进行,Python只需要检索固定成本为O(1)不要: len(queryset)– 这将执行SELECT * FROM some_table查询,获取整个表O(N)并需要额外的O(N)内存来存储它。 这是可以做的最糟糕的事情
- 
当你打算提取查询集时,使用 len()会稍微好一点,因为它不会导致额外的数据库查询,因为count()会:len(queryset) # fetching all the data - NO extra cost - data would be fetched anyway in the for loop for obj in queryset: # data is already fetched by len() - using cache pass计数: queryset.count() # this will perform an extra db query - len() did not for obj in queryset: # fetching data pass
- 
还原第二种情况(当查询集已被提取时): for obj in queryset: # iteration fetches the data len(queryset) # using already cached data - O(1) no extra cost queryset.count() # using cache - O(1) no extra db query len(queryset) # the same O(1) queryset.count() # the same: no query, O(1)
一旦你看了一眼就可以清楚一切:
 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) 
Django文档中的良好引用:
- 当QuerySets被评估
- 计数()