【问题标题】:Django Pagination too slow with large dataset大数据集的 Django 分页太慢
【发布时间】:2016-04-16 21:05:03
【问题描述】:

我对 Django 的分页有疑问。当我尝试对超过 200k 条记录进行分页时,门户网站的加载速度非常慢(> 10 秒),我想使用大约 200 万条记录。

我在 Stackoverflow 或其他网站上找不到针对此问题的 GOOD 特定修复。每次代码获得一个页面时,它都会执行 QuerySet,它会遍历一个非常大的数据集,从而使其变慢。

有人知道可以做什么吗?我到处搜索,无法解决这个问题。下面我发布代码以进行分页。 Paper_list 是:model.object.all().filter(category=x)(现在大约有 200k 个对象(它们也都属于该类别)。

def paginate_context(paper_list, request, context, source, author, title, term, date):
num_papers = len(paper_list) 
paginator = Paginator(paper_list, 4) # Show X papers per page
page = request.GET.get('page')
try:
    papers = paginator.page(page)
except PageNotAnInteger:
    # If page is not an integer, deliver first page.
    papers = paginator.page(1)
except EmptyPage:
    # If page is out of range (e.g. 9999), deliver last page of results.
    papers = paginator.page(paginator.num_pages)      
context['papers'] = papers
context['num_papers'] = num_papers
context['query_cat'] = create_request_str_and(context['cat'], source, author, title, term, date)

【问题讨论】:

  • 您对查询集排序(或过滤)的字段是否有索引?
  • 我愿意。类别 = models.CharField(db_index=True, max_length=200)。我知道计数可能有问题,但我尝试了一些方法来修复它,但没有取得多大成功。
  • 您能查一下实际的数据库查询(并在上面找到EXPLAIN SELECT 吗?)。也许值得将category 字段转换为ForeignKey,但这只是一个猜测。
  • 我在 SELECT 之前使用 EXPLAIN 运行了查询。但我不确定如何解释其结果。解释选择之后:|类别 |空 |索引 |空 | category_1da45b5bea657362_uniq | 602 |空 | 112172 | 100.00 |使用索引 | +----+-------------+------------------------------ -+------------+-------+----------------+----------- ---- 1 行,1 个警告(0.00 秒)
  • 我的意思是,你应该EXPLAIN 慢查询,而不是空的SELECT。如果您使用 Postgresql,有一个方便的服务:explain.depesz.com。还是您提供的结果是实际的解释结果?请通过 dpaste 或 gist 发布它,它不可读。

标签: python mysql django database pagination


【解决方案1】:

正如我在代码中看到的,num_papers = len(paper_list) 方法会评估查询,因此可能会影响性能。您可以将其更改为:

num_papers = paper_list.count()

您可以在此处查看查询集的评估时间:https://docs.djangoproject.com/en/1.9/ref/models/querysets/#when-querysets-are-evaluated

【讨论】:

  • 地精,鹰眼! ) 这绝对是真正的问题。
  • 这只是一行代码,显示有多少结果。有人告诉我这可能会影响性能。所以我评论了那条线。问题仍然存在。我尝试了您前段时间的建议,但没有改善加载时间。
  • 没关系。那确实解决了问题。谢谢!现在我有另一个问题。 model.objects.all().filter(category=context['cat']) 不返回它应该返回的所有记录,因为它只返回具有 1 个类别的记录。但是每条记录都可以关联多个类别。这有效:[item for item in model.objects.all() if any(category in item.category for category in context['cat'])] 但是执行时间太慢了。
  • 如果你能再问一个关于新问题的问题会更好,这样会更清楚:)。请接受我的回答,以便将来对其他人有所帮助:)
  • 当它允许我时会做一个新问题,因为我也尝试过解决最后一个问题但没有太大成功(因此,过度劳累用于 for() 以获得正确的记录)。采纳答案,再次感谢。
猜你喜欢
  • 2021-09-14
  • 1970-01-01
  • 2017-02-07
  • 2019-07-02
  • 2015-09-28
  • 1970-01-01
  • 2010-12-14
  • 1970-01-01
相关资源
最近更新 更多