Opened 18 years ago
Last modified 14 years ago
#7121 closed
Slicing on QuerySet bypasses result_cache — at Version 5
| Reported by: | Owned by: | nobody | |
|---|---|---|---|
| Component: | Uncategorized | Version: | dev | 
| Severity: | Keywords: | qsrf-cleanup queryset-rf, cache | |
| Cc: | Triage Stage: | Design decision needed | |
| Has patch: | no | Needs documentation: | no | 
| Needs tests: | no | Patch needs improvement: | no | 
| Easy pickings: | no | UI/UX: | no | 
Description (last modified by )
Playing around in the shell and watching postgresql.log I found out the following:
Method a)
list = Article.objects.filter(id__gt=130).order_by('-id')[0:2]
list[0] # Performs SQL query with LIMIT 1
list[1] # Performs another SQL query with LIMIT 1 OFFSET 2
Method b) 
list = Article.objects.filter(id__gt=130).order_by('-id')[0:2]
list # Performs an SQL query with LIMIT 2
list[0] # Hits the cache
list[1] # Hits the cache
Calling list[0] afterwards will invoke the SQL query with LIMIT 1
Calling
list[1]after this will invoke another query with LIMT 1 OFFSET 1
b) Calling just "list" afterwards first and then calling list[0] and list[1]
will honor the cache and therefore only one SQL query gets fired.
Change History (5)
comment:1 by , 18 years ago
comment:2 by , 18 years ago
It seems that QuerySet.getitem assumes that there is a cache (result_cache) already. This cache gets initialized/filled by calling repr or len since they trigger the iter which calls QuerySet.iterator. Calling getitem without repr or len before will not initialize the cache and will lead to subsequent select queries.
I would expect that 
list = Article.objects.filter(idgt=130).order_by('-id')[0:2]
calls performs a select with LIMIT 2 on the database and fills the cache with two enties, so that when I would call list[0] and list[1] would fetch their data from the cache and not from a SQL select.
comment:3 by , 18 years ago
| Summary: | queryset-rf does not always honor cache → Slicing on QuerySet bypasses result_cache | 
|---|
comment:4 by , 17 years ago
| Keywords: | qsrf-cleanup added | 
|---|
comment:5 by , 17 years ago
| Description: | modified (diff) | 
|---|
Ouch, sorry, text wasn't formatted properly.
Method a)
list = Article.objects.filter(idgt=130).order_by('-id')[0:2]
list[0] # Performs SQL query with LIMIT 1
list[1] # Performs another SQL query with LIMIT 1 OFFSET 2
Method b)
list = Article.objects.filter(idgt=130).order_by('-id')[0:2]
list # Performs an SQL query with LIMIT 2
list[0] # Hits the cache
list[1] # Hits the cache