Efficient way to perform many queries

73 views
Skip to first unread message

9dev...@gmail.com

unread,
Aug 15, 2014, 2:27:18 PM8/15/14
to django...@googlegroups.com
I am writing application similar to django-taggit and I was wondering about its performance.

Example for list of items:

{% for item in items %}

   
{{ item.name }}

   
{% for tag in item.tags.all %}
       
{{ tag }}
   
{% endfor %}

{% endfor %}

Above code creates massive amount of separated SQL queries as can be observed in Django Toolbar (click on image to enlarge).


Is there any way to make it more efficient? I was thinking about merging these queries into one big. Thanks in advance for any tips.

Collin Anderson

unread,
Aug 15, 2014, 2:46:33 PM8/15/14
to django...@googlegroups.com
you could try in your view:

items = items.prefetch_related('tags')


9dev...@gmail.com

unread,
Aug 15, 2014, 2:52:25 PM8/15/14
to django...@googlegroups.com
Thank you.

What if I'm using GenericForeignKey in Tags model? Can I still use it?

Sergiy Khohlov

unread,
Aug 15, 2014, 3:03:11 PM8/15/14
to django-users
good question ! 

1) I like to use some optimization at view side not template 
2) if i need something like your code I using optimization.
 Something like that : 

{% with items = mymodels.items.all  %}

{% for item in items %}

    {{ item.name }}

    {% for tag in item.tags.all %}
        {{ tag }}
    {% endfor %}

{% endfor %}

{% endwith %}
 
First records means get ALL record to the variable which should be cached and used sometimes later 


3) Anyway  i dont like  "object.all "
I like to retrieve minimum of the field for decreasing database loading 

Many thanks,

Serge


+380 636150445
skype: skhohlov


On Fri, Aug 15, 2014 at 5:46 PM, Collin Anderson <cmawe...@gmail.com> wrote:
you could try in your view:

items = items.prefetch_related('tags')


--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/0acd3536-93e7-463a-9805-06d1b9236b63%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

9dev...@gmail.com

unread,
Aug 16, 2014, 10:24:55 AM8/16/14
to django...@googlegroups.com
prefetch_related() works great.

How about prefetching some computed value instead of records?

{% for item in items %}

   
{{ item.name }}


   
{{ item.score }}

{% endfor %}

I want to prefetch 'score' for every item, where 'score' would be equivalent to:

score = Votes.objects.all().count() - Votes.objects.filter(value=False).count()

Is there any way to prefetch such query?

Code below prefetches all data for Vote records. How can it be changed to prefetch only the score?

Item.objects.all().prefetch_related('votes')



Collin Anderson

unread,
Aug 16, 2014, 9:54:24 PM8/16/14
to django...@googlegroups.com
I think this should work:

Item.objects.exclude(votes__value=False).annotate(score=Count('Votes'))

9dev...@gmail.com

unread,
Aug 17, 2014, 4:36:51 PM8/17/14
to django...@googlegroups.com
Thank you, it works perfectly :)
Reply all
Reply to author
Forward
0 new messages