Hi all,

I finally got fed up with the common performance problem of ending up
doing O(n) DB queries when you need the (many) related objects of a list
of objects, and did something about it:

https://code.djangoproject.com/ticket/16937

I'm pretty sure the concept is something desirable, the problem is the
implementation.

It is much uglier than I'd like, but I think the current way that
QuerySets/Managers/related managers interact make this inevitable.

The current behaviour also makes any kind of 3rd party monkey patching
solution extremely hard. For example, the related object descriptors
make it pretty hard to decorate instances of the queryset with some
proxy objects, because they intercept any assignment of attributes of
the same name. (i.e. if you have foo.bar_set, you can't do foo.bar_set
== some_precalculated_objects as a performance hack). And the way the
descriptors work mean that you get new manager objects (even new manager
*classes*) every time you access the property, and this really works
against any kind of monkey patching.

If you want to implement this outside core, and you don't want to change
templates and other code, I think you'd have to create a proxy for the
entire model instance, and I imagine it would be a total pain.

So, given how common this performance problem is, and how hard it is to
implement outside core, I think we should consider even an ugly
implementation. I think it is also inevitable that it is going to
involve QuerySet/related managers hacking each other's internals, or
duplicating to some extent. In my implementation, I put most of the
ugliness into QuerySet, and a few hooks into related managers. It might
be possible to clean it up a bit.

There is also a fairly nasty use of .extra() which is needed so that
after we retrieve M2M related objects in bulk we know which row on the
primary table they refer to.

I've got tests and docs in the patch on the ticket. I would say it is
more than proof-of-concept at this stage, but probably less than
finished patch - I may have forgotten some cases that we need to cover.

Feedback welcome!

Regards,

Luke

-- 
"I spilled spot remover on my dog. Now he's gone." (Steven Wright)

Luke Plant || http://lukeplant.me.uk/

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.

Reply via email to