Opened 17 years ago
Closed 17 years ago
#4739 closed (wontfix)
len(queryset) is slow
Reported by: | Owned by: | Adrian Holovaty | |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | dev |
Severity: | Keywords: | queryset, len, count, select | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
len(queryset) uses queryset.iterator, which performs SQL SELECT instead of SQL COUNT. queryset.len should instead call queryset.count() which is much faster as it will use the cached result of SELECT if available, otherwise performing a SQL COUNT.
Index: django/db/models/query.py
===================================================================
--- django/db/models/query.py (revision 5583)
+++ django/db/models/query.py (working copy)
@@ -106,7 +106,7 @@
return repr(self._get_data())
def len(self):
- return len(self._get_data())
+ return self.count()
def iter(self):
return iter(self._get_data())
Change History (2)
comment:1 by , 17 years ago
comment:2 by , 17 years ago
Resolution: | → wontfix |
---|---|
Status: | new → closed |
Your solution requires a second database query, which isn't so great.
If a user only wants the size of a set of results, they can call count() explicitly. If they are calling len() on the queryset, then they've already created the queryset for other reasons, so actually using the results we've already queried is efficient (recalling that the queryset is going to cache the results anyway).
All that being said, one enhancement that will be introduced soon is to speed up len() for most database backends by using the cursor's rowcount attribute and (only if that isn't implemented) then falling back to the size of the result set.
So, yes, we can make len() slightly more efficient for most database backends (not SQLite, but life's like that sometimes), but it isn't going to be by making another database call.
The patch again wrapped in a code block: