Opened 13 years ago
Closed 3 years ago
#16063 closed Cleanup/optimization (fixed)
Unnecessary joins in admin changelist query
Reported by: | Evgeny Sizikov | Owned by: | Jacob Walls |
---|---|---|---|
Component: | contrib.admin | Version: | 1.2 |
Severity: | Normal | Keywords: | |
Cc: | goblinJoel | Triage Stage: | Ready for checkin |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Django 1.2.5
Models:
class Client(models.Model): name = models.CharField(_('name'), max_length=256) name2 = models.CharField(_('unofficial or obsolete name'), max_length=256, blank=True, null=True) contact_person = models.CharField(_('contact person'), max_length=256, blank=True, null=True) ... class ClientOffice(models.Model): name = models.CharField(_('name'), max_length=256) name2 = models.CharField(_('unofficial or obsolete name'), max_length=256, blank=True, null=True) ... client = models.ForeignKey(Client, verbose_name=_('client')) ...
and admin options like these:
class ClientAdmin(admin.ModelAdmin): search_fields = ('name', 'name2', 'contact_person', 'clientoffice__name', 'clientoffice__name2') ...
Numbers:
>>> Client.objects.count() 10907 >>> ClientOffice.objects.count() 16952
Now, if we try searching for clients in admin by a search query containig several words (>3), got django/admin stalled.
The problem is going to be that each word in the search query leads to additional JOIN in final SQL query beacause of qs = qs.filter(...)
pattern. The attached patch is for Django 1.2.5, but adopting for the current SVN trunk is trivial.
Attachments (1)
Change History (16)
by , 13 years ago
Attachment: | django_1_2_5_admin_search_m2m_prevent_multiple_joining.diff added |
---|
comment:1 by , 13 years ago
comment:2 by , 13 years ago
Needs tests: | set |
---|---|
Triage Stage: | Unreviewed → Accepted |
Looking at the code, the part that is modified by the patch is not modified in current trunk. The problematic pattern is still there:
for bit in self.query.split(): ... qs = qs.filter(...)
comment:3 by , 13 years ago
Type: | Bug → Cleanup/optimization |
---|
comment:4 by , 13 years ago
I have checked with Django 1.3 and can now confirm that the problem is still there. Django's ORM in 1.3 still generates SELECT with JOIN's for each qs = qs.filter(...)
call, which is going to be made per term in a search query.
comment:6 by , 6 years ago
Cc: | added |
---|
This is old, but I think it's a good idea. It's still a problem in Django 1.11, and I didn't see any changes in the 2.x code that looked relevant. It can end up devouring storage space larger than the db itself and suck up CPU to the point where the database system becomes unresponsive or runs out of storage.
I'm not sure whether I should be making unilateral edits, so I suggest renaming to something like:
Multi-word admin searches hang with foreign keys in search_fields
Related:
- https://github.com/django/django/pull/7277 with a similar solution
- https://groups.google.com/forum/#!topic/django-developers/V8M49P326dI thread related to above PR
- https://code.djangoproject.com/ticket/27864 more recent attempt to mitigate by limiting how many search terms you can use
comment:7 by , 3 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:8 by , 3 years ago
Summary: | Problem with searching in m2m fields in inherited model → Unnecessary joins in admin changelist query |
---|
comment:12 by , 3 years ago
Needs documentation: | set |
---|---|
Patch needs improvement: | set |
comment:13 by , 3 years ago
Needs documentation: | unset |
---|---|
Patch needs improvement: | unset |
comment:14 by , 3 years ago
Triage Stage: | Accepted → Ready for checkin |
---|
patch has been made from Mercurial repository