Opened 6 years ago

Last modified 6 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.

Change History (0)

Note: See TracTickets for help on using tickets.
Back to Top