Opened 27 hours ago

Last modified 8 hours ago

#37287 assigned Cleanup/optimization

Add Index on LogEntry.action_time to optimize admin dashboard performance — at Initial Version

Reported by: Ali Rafiei Owned by:
Component: contrib.admin Version: dev
Severity: Normal Keywords: admin, index, logentry, performance
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Problem & Motivation

In high-traffic production environments, the django_admin_log table often grows to millions of rows. Every time a user loads the main Django Admin Index (dashboard) page, the framework displays the "Recent actions" sidebar. This forces the following query to execute: 

SELECT ... FROM "django_admin_log" ORDER BY "django_admin_log"."action_time" DESC LIMIT 10;

Because LogEntry explicitly defines ordering = -action_time in its Meta options but lacks any indexing on the action_time field, database engines must perform a highly inefficient sequential table scan to retrieve these 10 rows. This causes severe CPU spikes and long page-load delays on large datasets, as highlighted in recent community discussions (e.g., Django Forum thread #41943). 

Historical Context & Precedent

The structural performance limitations of django_admin_log are well-documented. Similar bottlenecks regarding missing indexes were flagged in Ticket #17659 and Ticket #36414

While previous community efforts to index django_admin_log faced roadblocks—specifically regarding the object_id column because MySQL struggles to index unbounded text columns—action_time is a standard DateTimeField. Adding an index here carries no cross-database compatibility issues and is universally supported across PostgreSQL, MySQL, SQLite, and Oracle. 

Proposed Solution
To address this bottleneck, I propose adding an explicit descending index on action_time directly to LogEntry.Meta.indexes (e.g., models.Index(fields=-action_time and generate the corresponding core migration for contrib.admin. This targets an un-bypassable query built into Django's default UI and guarantees predictable performance scaling for enterprise installations.

Change History (0)

Note: See TracTickets for help on using tickets.
Back to Top