Opened 15 years ago
Closed 15 years ago
#13643 closed (duplicate)
Admin changelist page very slow with postgresql and a huge table
| Reported by: | marcob | Owned by: | nobody |
|---|---|---|---|
| Component: | contrib.admin | Version: | 1.2 |
| Severity: | Keywords: | ||
| Cc: | Triage Stage: | Unreviewed | |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
Postgresql count(*) is a slooow operation because it forces a full table scan.
It would be nice to have an admin option to disable full counts and only provide previous/next-based navigation.
As a workaround you could get this LazyPaginator http://github.com/andymckay/lazy_paginator and write a bit of (ugly) monkey patching:
# Lazy pagination
from lazypaginator import LazyPaginator, InvalidPage
from django.contrib.admin.views import main
_ChangeList = main.ChangeList
_get_results = main.ChangeList.get_results
class ChangeList(_ChangeList):
def get_results(self, request):
if not getattr(self.model_admin, 'lazy_pagination', False):
return _get_results(self, request)
paginator = LazyPaginator(self.query_set, self.list_per_page, max_safe_pages=5)
full_result_count = result_count = paginator.max_safe_pages * self.list_per_page
can_show_all = False
multi_page = result_count > self.list_per_page
# Get the list of objects to display on this page.
try:
result_list = paginator.page(self.page_num+1).object_list
except InvalidPage:
result_list = ()
self.result_count = result_count
self.full_result_count = full_result_count
self.result_list = result_list
self.can_show_all = can_show_all
self.multi_page = multi_page
self.paginator = paginator
setattr(main, 'ChangeList', ChangeList)
Then you could use in your model admin:
lazy_pagination = True
Pro: no more changelist delay with huge table
Con: wrong record count
Ciao.
Marco.
Note:
See TracTickets
for help on using tickets.
Dupe of #8408