﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
10697	contrib.admin is slow with large, complex datasets	mrts	nobody	"Suppose I have a complex admin page that, given the following models:
{{{
class A(models.Model):
    name = models.CharField(...)
    # 10 more fields, some of them e.g. TextFields()

    def __unicode__(self):
        return self.name

class B(models.Model):
    name = models.CharField(...)
    # 10 more fields, some of them e.g. TextFields()

    def __unicode__(self):
        return self.name

class C(models.Model):
    name = models.CharField(...)
    a = models.ForeignKey(A)
    b = models.ForeignKey(B)
    is_published = models.BooleanField()
    # 10 more fields, some of them e.g. TextFields()
}}}
has to display the following in admin change list:
{{{
class CAdmin(admin.ModelAdmin):
    list_display = ('name', 'a', 'b', 'is_published')
    list_filter = ('a',)
}}}

The SQL for the change list view is as follows:
 1. `SELECT COUNT(*) FROM app_c` to calculate the number of pages for pagination,
 1. `SELECT * FROM app_c ORDER BY app_a.id DESC LIMIT 100 OFFSET 300` to show the objects on a particular page,
 1. for each result int the previous object set,  `SELECT * FROM app_a` and `SELECT * FROM app_b` to display the string representations of `a` and `b`. (Actually, as `a` is used in filtering, it will not generate the extra queries.)

This can be improved by:
 1. making `COUNT(*)` optional (see #8408),
 1. use `QuerySet.only()` to only select the non-foreign key fields that are actually used (`name` and `is_published` in this case),
 1. use a join to avoid the `n` additional queries for foreign keys (the display fields have to be explicitly controlled by `list_display = ('name', 'a__name', 'b__name', 'is_published')`, see #3400).

As a result, only the following single query should be executed:
{{{
SELECT app_c.name, app_a.name, app_b.name, app_c.is_published
    FROM app_c, app_a, app_b
    WHERE app_c.a_id = app_a.id AND app_c.b_id = app_b.id
    ORDER BY app_c.id DESC LIMIT 100 OFFSET 300
}}}"		closed	contrib.admin	dev		invalid	efficient-admin		Unreviewed	0	0	0	0	0	0
