Django annotate() 性能 - 它应该超级慢吗?

rau*_*uff 5 python django database-design django-models django-orm

annotate() 使事情变得缓慢如爬行一样正常吗?

使用这样的注释:

post_list = j.post_set.all().annotate(num_comments=Count('comment')).order_by('-pub_date')
Run Code Online (Sandbox Code Playgroud)

与不做注释相比,花费的时间是原来的四倍:

post_list = j.post_set.all().order_by('-pub_date')
Run Code Online (Sandbox Code Playgroud)

我还尝试使用 value() 和 defer() ,但这些也没有帮助。将评论数量保留为 Post 表中的字段是唯一真正的选择吗?

顺便说一句,我正在使用MySQL。

Tho*_*mas 1

因此,对于简单的情况,post_list = j.post_set.all().order_by('-pub_date')您正在对数据库中的单个表进行查询。这会很快,如果在字段上添加索引,速度会更快pub_date。并ordering = ['-pub_date']在 Post 的 Meta 部分中进行设置。

对于作为注释的更复杂的情况,对于您要求的每条记录,它需要在相关表中进行查找并计算返回的条目数。即使直接从索引中提取数据,这也必然比简单情况花费更长的时间。

为了进行故障排除,我建议您安装django-debug-toolbar,查看它的查询选项卡,找到拖慢您速度的查询,然后运行该explain工具以获取有关拖慢您速度的原因的额外信息。该工具将向您显示生成的确切 SQL,以及查询的哪些部分“成本”最高。

如果它让您速度减慢,也许您应该考虑将此信息存储在缓存中。或者使用像 postgres 这样的数据库,它允许您将这种元信息存储在自定义索引中。