python - 从庞大且不断增长的数据集中优化慢速 Django 查询集

标签 python django performance postgresql django-queryset

我的页面加载速度太慢。我需要以某种方式改进查询数据的方式(缓存?部分加载/页面?等)

请注意,我是一个 django 菜鸟,还没有完全了解 model.Managermodels.query.QuerySet 所以如果这个设置看起来很尴尬...... ..

目前,页面加载查询集大约需要 18 秒,目前只有大约 500 条记录。平均每天大约有 100 条新记录。

Network stats

数据库是Postgresql

缓慢的 View :

def approvals(request):
    ...
    approved_submissions = QuestSubmission.objects.all_approved()
    ...

缓慢的查询集:

class QuestSubmissionQuerySet(models.query.QuerySet):
    ...

    def approved(self):
        return self.filter(is_approved=True)

    def completed(self):
         return self.filter(is_completed=True).order_by('-time_completed')

    ...

class QuestSubmissionManager(models.Manager):
    def get_queryset(self):
        return QuestSubmissionQuerySet(self.model, using=self._db)

    def all_approved(self, user=None):
        return self.get_queryset().approved().completed()

    ...

QuestSubmission.objects.all_approved() 生成的 SQL:

'SELECT "quest_manager_questsubmission"."id", "quest_manager_questsubmission"."quest_id", "quest_manager_questsubmission"."user_id", "quest_manager_questsubmission"."ordinal", "quest_manager_questsubmission"."is_completed", "quest_manager_questsubmission"."time_completed", "quest_manager_questsubmission"."is_approved", "quest_manager_questsubmission"."time_approved", "quest_manager_questsubmission"."timestamp", "quest_manager_questsubmission"."updated", "quest_manager_questsubmission"."game_lab_transfer" FROM "quest_manager_questsubmission" WHERE ("quest_manager_questsubmission"."is_approved" = True AND "quest_manager_questsubmission"."is_completed" = True) ORDER BY "quest_manager_questsubmission"."time_completed" DESC'

慢速模型:

class QuestSubmission(models.Model):
    quest = models.ForeignKey(Quest)
    user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name="quest_submission_user")
    ordinal = models.PositiveIntegerField(default = 1, help_text = 'indicating submissions beyond the first for repeatable quests')
    is_completed = models.BooleanField(default=False)
    time_completed = models.DateTimeField(null=True, blank=True)
    is_approved = models.BooleanField(default=False)
    time_approved = models.DateTimeField(null=True, blank=True)
    timestamp = models.DateTimeField(auto_now=True, auto_now_add=False)
    updated = models.DateTimeField(auto_now=False, auto_now_add=True)
    game_lab_transfer = models.BooleanField(default = False, help_text = 'XP not counted')

    class Meta:
        ordering = ["time_approved", "time_completed"]

    objects = QuestSubmissionManager()

    #other methods
    ....

有什么策略可以解决这个问题?我尝试使用 django 的分页器,但它似乎只显示在页面中,但它仍然加载整个查询集。

最佳答案

首先要看:

  • 这个查询很慢是因为它返回了一个非常大的结果集吗?

  • 这个查询很慢是因为它需要一段时间来过滤表格吗?

假设是前者,除了“返回更少的数据”之外,您没有太多好的选择。

如果是后者,您可能应该在数据库上运行 EXPLAIN,但马上我会说您可能需要一个索引,可能在 (is_approved, is_completed) 上。这可以通过以下方式完成:

class Meta:
    index_together = [
        ["is_completed", "is_approved"],
    ]

关于python - 从庞大且不断增长的数据集中优化慢速 Django 查询集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32670603/

相关文章:

python - 在图像中的一组点周围找到不同的边界

python - 无论如何,在退出时关闭sqlite3数据库

python - 最接近零的两个产品之间的差异 : non brute-force solution?

Python 列表到位运算

node.js - NSolid SaaS 的不同计划包括哪些内容?

python - 如何使用 Python 和 BeautifulSoup 选择此页面上的 87%

css - apache 服务器上的 django 管理 css

python - 序列化可选的嵌套结构 : Difference between QueryDict and normal dict?

c# - 性能——FunctionCall vs Event vs Action vs Delegate

python - 基于数组的子集填充列