Reputation: 1390
How much of a performance difference is there between these two type of queries?
Say I have these 3 models:
class Brand(models.Model):
brand_name = models.CharField()
class Model(models.Model):
brand = Models.ForeignKey(Brand)
model_name = models.CharField()
class Listing(models.Model):
model = Models.ForeignKey(Model)
listing_info = models.CharField()
I have several thousand listings that I am showing in the templates and I would like to display the brand_name and model_name for each listing.
In the templates I list this as such:
<p>{{ listing.model.brand.brand_name }}</p>
<p>{{ listing.model.model_name }}</p>
<p>{{ listing.listing_info }}</p>
Now consider if I listed those values right in the Listing model (duplicate the data):
class Listing(models.Model):
model = Models.ForeignKey(Model)
brand_name = models.CharField()
model_name = models.CharField()
listing_info = models.CharField()
Then in the templates I could simply list as such:
<p>{{ listing.brand_name }}</p>
<p>{{ listing.model_name }}</p>
<p>{{ listing.listing_info }}</p>
Thinking beyond the problem of having data duplication, how much of a performance difference is there between the two setups?
Upvotes: 0
Views: 31
Reputation: 308769
If you use select_related
, then Django will fetch the related model
and brand
data at the same time as it fetches the listings.
Listing.objects.filter().select_related('model', 'model__brand')
As an example, say you have 100 listings. Without select_related
, there would be 201 queries (1 query to fetch all the listings, 100 to fetch each listing's model and 100 to fetch each model's brand). With select_related
, everything is fetched in 1 query.
In theory, denormalizing the data (duplicating attributes in the Listing
model) might offer a further performance benefit, but the improvement would probably be negligible. You would have to measure it to see. Most of the time, using select_related
is good enough.
Upvotes: 4