I'm trying to improve the performance of a Django app, and noticed
that you can't seem to properly defer fields when making lookups with
joins. To demonstrate, I set up a test project with the following
models:
class ATestModel(models.Model):
other = models.ForeignKey('OtherModel')
class OtherModel(models.Model):
name = models.CharField(max_length=32)
then, in the Django shell, I set up 10 'ATestModel's and two
'OtherModel's properly linked up, and ran the following:
>>> from testmodule import models
>>> testmodels = models.ATestModel.objects.all().only('other__name')
>>> print testmodels[0].other.name
Test One
>>> from django.db import connection
>>> print '\n\n'.join([x['sql'] for x in connection.queries])
SELECT "testmodule_atestmodel"."id",
"testmodule_atestmodel"."other_id" FROM "testmodule_atestmodel" LIMIT
1
SELECT "testmodule_othermodel"."id", "testmodule_othermodel"."name"
FROM "testmodule_othermodel" WHERE "testmodule_othermodel"."id" = 1
I also re-ran that without the 'only' call:
>>> testmodels = models.ATestModel.objects.all()
>>> print testmodels[0].other.name
Test One
>>> print '\n\n'.join([x['sql'] for x in connection.queries[2:]])
SELECT "testmodule_atestmodel"."id",
"testmodule_atestmodel"."other_id" FROM "testmodule_atestmodel" LIMIT
1
SELECT "testmodule_othermodel"."id", "testmodule_othermodel"."name"
FROM "testmodule_othermodel" WHERE "testmodule_othermodel"."id" = 1
The 'only' call does nothing, and two queries are made when one would
have sufficed (SELECT testmodule_othermodel.name FROM
testmodule_atestmodel LEFT JOIN testmodule_othermodel ON
testmodule_atestmodel.id = testmodule_othermodule.id). This raises a
huge performance penalty for highly normalized schemas and I would
even go so far as to say it in fact makes it impossible to optimize
queries with a decently normalized schema.
My apologies if someone has brought this up before - I was unable to
see anything about it in the django tickets or mailing lists.
--
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+unsubscribe@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/django-users?hl=en.
No comments:
Post a Comment