Hi!

Thanks for all your suggestions. I've been able to solve the issue.
Now the page reports to be executing roughly 80-90 SQL queries and is
performing well.

The problem was mainly in two places of my code where I was looping
through all the results of a related set for every row in a paged
object. The problem hasn't become evident earlier because being an
intranet application, the site does not receive much traffic.

Once the related set has started to grow, the problem has emerged.

I was doing something like this:

{% for element in mypagedlist.object_list %}
    {% for related_element in element.related_element_set.all %}
        #Do something
    {% endfor %}
{% endfor %}

Regarding the snippet 461, I am using the Django Debug Toolbar, which
has helped me a lot: 
http://github.com/robhudson/django-debug-toolbar/tree/master

Regarding, select_related, first I was having trouble because it
wasn't following foreign keys that allowed blank=True. After
specifying the fields to follow, it started to work. But even while
being able to drop the number of SQL queries to around 10-15, the
query itself was taking much longer to execute. The page performs much
better doing 90 simple SQL queries, than 10-15 with 1 that is complex.

Since at first I didn't know what was happening, I introduced caching
via the simple local memory cache.
In this way I've been able to also reduce some queries that where
being repeated in different parts of the site.
What I am not so clear about is if this will report any important
benefit, since the SQL part has never been the bottleneck. So placing
some querysets or objects in the cache instead of the mysql db doesn't
result in such a big performance gain. (Still, the cache needs to
pickle, unpickle things and you need more logic to control that the
cache gets updated as it should and contains the keys you expect.)
It does seem much more interesting to cache a whole page or page
fragment, since that caching occurs with the template being already
rendered, so this can potentially increase a lot the performance.
The problem with that approach on pages that have a lot of calculated
data on them is that the cached page is likely to get outdated very
quickly.

One thing that I'm not sure if it's a fault of mine is that the
cache.add() method throws a NotImplementedError, even though in the
documentation it says it's available...
Now I've set up a function that will handle the get and set of the
cache like this:

def obtain_from_cache(key):
    key_list = key.split('_') # This is a small convention for knowing
what to call
    if key_list[0] == 'MYGROUPOFKEYS':
        result = cache.get(key)
        if not result:
            result = cache.set(key, Group.objects.get
(id__exact=key_list[1]).user_set.all())) #This is just an example
        return result

This code works well for keys that you simply will never want to
change before they expire.
If someone has a better way of working with the cache, please comment.

My conclusion in the end is that you have to pay a lot of attention to
what information you expose in the templates. Being able to call
object methods in the template is very powerful indeed, but can lead
to important problems if you don't pay attention at what you do.

Another thing learned is that having querysets which are evaluated
lazyly doesn't mean you can also start being lazy with your code ;)


Regarding the server setup:

Has anyone experience with mod_wsgi on Windows? I've read that, since
it's Windows, mod_wsgi can't be run in daemon mode and that means the
performance gain won't be that much over mod_python.


Again, thanks for the support.

Stefan

On 28 mayo, 17:39, Steve Howell <showel...@yahoo.com> wrote:
> On May 28, 8:19 am, jrs_66 <jrs...@yahoo.com> wrote:
>
> > 250 queries on one page seems to me to be dangerously high.  I would
> > have to guess you could reduce that significantly.  Turn on query
> > output to see if the Django ORM isn't creating sloppy queries in
> > loops.  My guess is that with some code alterations you could help....
>
> This seems like a good place to start to me.
>
> As far as debugging, there might be some tools on djangosnippets that
> might help the original poster:
>
> http://www.djangosnippets.org/snippets/461/
>
> As somebody else suggested on the thread, I'm not entirely sure about
> the diagnosis that the template rendering is really the bottleneck,
> since queries are lazily executed.
>
> For debugging purposes, you can force queries to be executed earlier
> with little impact on the template by turning them into lists, which
> helps you to more easily identify bottlenecks (but not good for prod,
> it uses more memory).
>
>     objs = list(objs)
>
> To reduce the sheer number of queries, I recommend experimenting the
> select_related() feature.  I haven't used it in Django, but I've used
> equivalent features in Rails, and it can lead to pretty drastic
> speedups, but I'll give the caveat that I was usually trying to reduce
> delays from latency.  Here are docs on select_related():
>
> http://docs.djangoproject.com/en/dev/ref/models/querysets/#id4
>
> Also, as always, it might make good sense to simply divide and
> conquer, refactor as you go, etc
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com
To unsubscribe from this group, send email to 
django-users+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to