python - Django ORM 注释性能
问题描述
我在工作中使用 Django 和 Django REST Framework,最近我们在几个端点上遇到了一些性能问题。我们首先确保 SQL 部分已优化,没有不必要的 N+1 查询,可能的索引等。
查看数据库部分本身,它似乎非常快(总共 3 个 SQL 查询,不到一秒),即使是更大的数据集,但 API 端点仍然需要超过 5 秒才能返回。我开始使用几个不同的工具来分析 Python 代码,并且大部分时间总是花在Django 中的annotate
and函数中。set_group_by
我尝试谷歌搜索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_related
和prefetch_related
都在那里,索引也在那里。
我尝试完全不重写代码annotate
,但似乎没有帮助。我开始想知道所花费的时间annotate
是否真的是一个红鲱鱼,这只是分析器如何看待它,但我尝试的所有分析器都显示了同样的事情。
虽然我觉得我对 Django 非常了解并且之前成功地优化了 API 端点,但我不确定在这种情况下要拉什么“线程”。我尝试查看 Django 内部结构,尤其是在周围annotate
,set_group_by
但无法确定在那里花费的时间。我最后的努力是尝试用原始 SQL 重写这两个端点,但我非常想避免这种情况。
所有的帮助都会得到很大的帮助:)
解决方案
推荐阅读
- android - 覆盖数据类中的 val
- python-3.x - 动态更改数据库 SQLAlchemy 实例的架构
- ms-access-2016 - 如何设计查询以给出链接到每组数据的每个相关字段的名称
- android - 在Android中检测总手指触摸
- java - Crypt 通过使用 RESTEasy 的注释来解密 java 对象 ID
- ruby-on-rails - 组合两个范围具有相同的 .select
- node.js - 每次我使用 Number() 函数时都会出错
- excel - 为什么Excel宏忽略新添加的列
- ios - 如果在 UITextView 中设置了大的属性文本,scrollRangeToVisible(_:) 是否被认为很慢?
- java - 尽管未使用复合键,但收到错误“外键必须与引用的主键具有相同的列数”