Reputation: 5793
I have Pick
model which when I select a record within Django Admin takes an age (about 20 seconds) to retrieve the record (there are about 70k). However, it is quick when I try and create/save a record. I have added the indexes to try and speed up retrieval but don't really know what I should be doing
class Pick (models.Model):
team = models.ForeignKey(Team, on_delete=models.CASCADE, null=True, blank=True)
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, db_index=True)
contest_entry=models.ForeignKey(ContestEntry, on_delete=models.CASCADE, db_index=True)
game_round=models.ForeignKey(GameRound, on_delete=models.CASCADE, db_index=True)
objects = DataFrameManager()
def __str__(self):
return f'%s %s' % (self.contest_entry, self.game_round)
class Meta:
unique_together = ['user', 'contest_entry', 'game_round']
ordering = ['contest_entry','game_round','user','team']
index_together = [["user", "contest_entry", 'game_round'],]
indexes = [
models.Index(fields=['user', 'contest_entry', 'game_round']),
models.Index(fields=['game_round'], name='game_round_idx'),
models.Index(fields=['contest_entry'], name='contest_entry_idx'),
]
class PickAdmin(admin.ModelAdmin):
model = Pick
list_filter= (
('user', RelatedDropdownFilter),
('contest_entry__contest', RelatedDropdownFilter),
('game_round', RelatedDropdownFilter)
)
def get_queryset(self, request):
return super().get_queryset(request).select_related('user','contest_entry','game_round')
admin.site.register(Pick, PickAdmin)
How can I improve performance here?
Upvotes: 5
Views: 1750
Reputation: 6107
The key is specifying the raw_id_fields
on the admin class. The default <select>
widget for foreign key relationships can cause a lot of overhead retrieving and rendering all the options.
class PickAdmin(admin.ModelAdmin):
model = Pick
list_filter= (
('user', RelatedDropdownFilter),
('contest_entry__contest', RelatedDropdownFilter),
('game_round', RelatedDropdownFilter)
)
raw_id_fields = ('user', 'contest_entry', 'game_round',)
def get_queryset(self, request):
return super().get_queryset(request).select_related('user','contest_entry','game_round')
Upvotes: 5
Reputation: 1846
You can improve the queries by using select_related for foreignkeys https://docs.djangoproject.com/en/2.2/ref/models/querysets/#select-related
Upvotes: 0
Reputation: 29977
My guess is that what takes so long is rendering the dropdowns for the ForeignKey
fields of your model.
I'd suggest looking at the SQL queries that are performed, either by installing Django toolbar or enabling logging in your database server.
Upvotes: 1