Opened 7 years ago
Last modified 7 years ago
#29340 closed Cleanup/optimization
"cache.get_or_set()" extra hits on database — at Initial Version
Reported by: | hematinik | Owned by: | nobody |
---|---|---|---|
Component: | Core (Cache system) | Version: | 2.0 |
Severity: | Normal | Keywords: | cache |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
I've found out that using cache.get_or_set()
causes extra SQL queries while using the alternative approach to get a key’s value or set a value if the key isn’t in the cache (using "if" statement) works fine without extra hits on database.
it seems the problem appears when you use the cache.get_or_set()
inside a loop . this is the code to reproduce the problem:
THE MODEL:
class EventManager(models.Manager): def get_location(self,event): output = cache.get_or_set( 'event_location_eID{}'.format(event.pk), event.location, None) return output class Event(models.Model): objects = EventManager() location = models.ForeignKey(Location,on_delete = models.CASCADE)
THE VIEW:
def home(request): events = cache.get_or_set('all_events',Event.objects.all(),None) # this line works fine without extra hits on db locations = [] for event in events: x = Event.objects.get_location(event) # this line causes extra SQL queries while the cache keys already exist locations.append(x) return render(request,'index.html',{'locations':locations})
THE TEMPLATE:
{% for location in locations %} {{location.title}} <br> {% endfor %}
now if I change the get_location()
method on EventManager
to this:
def get_location(self,event): output = cache.get('event_location_eID{}'.format(event.pk)) if output is None: output = event.location cache.set('event_location_eID{}'.format(event.pk),output,None) return output
there will be no more unnecessarily SQL queries.
I'm using django-debug-toolbar to monitor my database requests and the information about queries is based on the statistics that django-debug-toolbar provides. I'll also attach some screenshots from django-debug-toolbar to clarify the situation.
Regards.