[Django Code] #4739: len(queryset) is slow

1 view
Skip to first unread message

Django Code

unread,
Jul 2, 2007, 1:10:52 AM7/2/07
to djang...@holovaty.com, ja...@jacobian.org, django-...@googlegroups.com
#4739: len(queryset) is slow
------------------------------+---------------------------------------------
Reporter: tcl...@umd.com.au | Owner: adrian
Status: new | Component: Database wrapper
Version: SVN | Keywords: queryset, len, count, select
Stage: Unreviewed | Has_patch: 1
------------------------------+---------------------------------------------
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())

--
Ticket URL: <http://code.djangoproject.com/ticket/4739>
Django Code <http://code.djangoproject.com/>
The web framework for perfectionists with deadlines

Django Code

unread,
Jul 2, 2007, 1:12:51 AM7/2/07
to djang...@holovaty.com, ja...@jacobian.org, django-...@googlegroups.com
#4739: len(queryset) is slow
--------------------------------------------+-------------------------------
Reporter: tcl...@umd.com.au | Owner: adrian
Status: new | Component: Database wrapper
Version: SVN | Resolution:
Keywords: queryset, len, count, select | Stage: Unreviewed
Has_patch: 1 | Needs_docs: 0
Needs_tests: 0 | Needs_better_patch: 0
--------------------------------------------+-------------------------------
Changes (by tcl...@umd.com.au):

* needs_better_patch: => 0
* needs_tests: => 0
* needs_docs: => 0

Comment:

The patch again wrapped in a code block:
{{{
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())
}}}

--
Ticket URL: <http://code.djangoproject.com/ticket/4739#comment:1>

Django Code

unread,
Jul 2, 2007, 1:28:27 AM7/2/07
to djang...@holovaty.com, ja...@jacobian.org, django-...@googlegroups.com
#4739: len(queryset) is slow
--------------------------------------------+-------------------------------
Reporter: tcl...@umd.com.au | Owner: adrian
Status: closed | Component: Database wrapper
Version: SVN | Resolution: wontfix
Keywords: queryset, len, count, select | Stage: Unreviewed
Has_patch: 1 | Needs_docs: 0
Needs_tests: 0 | Needs_better_patch: 0
--------------------------------------------+-------------------------------
Changes (by mtredinnick):

* status: new => closed
* resolution: => wontfix

Comment:

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.

--
Ticket URL: <http://code.djangoproject.com/ticket/4739#comment:2>
Reply all
Reply to author
Forward
0 new messages