首页 > 解决方案 > Django ORM 注释性能

问题描述

我在工作中使用 Django 和 Django REST Framework,最近我们在几个端点上遇到了一些性能问题。我们首先确保 SQL 部分已优化,没有不必要的 N+1 查询,可能的索引等。

查看数据库部分本身,它似乎非常快(总共 3 个 SQL 查询,不到一秒),即使是更大的数据集,但 API 端点仍然需要超过 5 秒才能返回。我开始使用几个不同的工具来分析 Python 代码,并且大部分时间总是花在Django 中的annotateand函数中。set_group_by

debug_toolbar_screenshot

我尝试谷歌搜索annotate和性能,查看 Django 文档,但没有提到它是一个“昂贵”的操作,特别是在与F函数一起使用时。

annotate部分代码如下所示:

qs = qs.annotate(
    foo_name=models.F("foo__core__name"),
    foo_birth_date=models.F("foo__core__birth_date"),
    bar_name=models.F("bar__core__name"),
    spam_id=models.F("baz__spam_id"),
    spam_name=models.F("baz__spam__core__name"),
    spam_start_date=models.F("baz__spam__core__start_date"),
    eggs_id=models.F("baz__spam__core___eggs_id"),
    eggs_name=models.F("baz__spam__eggs__core___name"),
)

qs = (
    qs.order_by("foo_id", "eggs_id", "-spam_start_date", "bar_name")
    .values(
        "foo_name",
        "foo_birth_date",
        "bar_name",
        "spam_id",
        "spam_name",
        "eggs_id",
        "eggs_name",
    )
    .distinct()
)

查询很大,跨越多个关系,所以我确定问题与数据库有关,但似乎不是。所有的select_relatedprefetch_related都在那里,索引也在那里。

我尝试完全不重写代码annotate,但似乎没有帮助。我开始想知道所花费的时间annotate是否真的是一个红鲱鱼,这只是分析器如何看待它,但我尝试的所有分析器都显示了同样的事情。

虽然我觉得我对 Django 非常了解并且之前成功地优化了 API 端点,但我不确定在这种情况下要拉什么“线程”。我尝试查看 Django 内部结构,尤其是在周围annotateset_group_by但无法确定在那里花费的时间。我最后的努力是尝试用原始 SQL 重写这两个端点,但我非常想避免这种情况。

所有的帮助都会得到很大的帮助:)

标签: pythondjangodjango-rest-framework

解决方案


推荐阅读