哪个是更有效的方法,使用列表理解或django的'values_list'函数?

问题描述 投票:1回答:2

尝试从django对象返回值列表时,使用列表解析会更好:

[x.value for x in Model.objects.all()]

或者在django的values_list函数上调用list():

list(Model.objects.values_list('value', flat=True))

为什么?

django python-3.x performance
2个回答
6
投票

最有效的方法是采用第二种方法(使用values_list())。原因是这会修改发送到数据库的SQL查询,只选择提供的值。

第一种方法FIRST从数据库中选择所有值,然后再次过滤它们。因此,您已经“花费”资源来使用该方法获取所有值。

您可以将通过将QuerySet包装生成的查询与str(queryset.query)进行比较,它将返回执行的实际SQL查询。

见下面的例子

class Model(models.Model):
    foo = models.CharField()
    bar = models.CharField()

str(Model.objects.all().query)  
# SELECT "model"."id", "model"."foo", "model"."bar" FROM "model"

str(Model.objects.values_list("foo").query)
# SELECT "model"."foo" FROM "model"

1
投票

我也有点认为目前接受的答案中的论点是正确的。也就是说,获取较少数量的字段会导致Model.objects.all()执行时间比Model.objects.values_list('foo')少。但是,在使用%timeit时,我没有在实践中发现这一点。

我实际上发现做Model.objects.values_list('foo', flat=True)需要比Model.objects.all()长2-10倍。我发现这是事实

  • 一张空的django桌子
  • 一个有10行的表
  • 一个包含数百万行的表

包括/ remove flat = True似乎对values_list的执行时间没有显着影响。我会对其他人发现的东西感兴趣吗?

所以这让我从一个纯粹的“执行什么SQL”的角度思考,尽管values_list ORM查询从db中获取的字段值较少,我想在.all() vs .values_list()的源django代码中仍有更多逻辑可能导致到不同的额外执行时间(包括.all()花费更少的时间)。

但是,为了完全解决初始示例代码,我们还需要考虑影响执行时间的任何进一步考虑,因为在[]案例中使用.all()案例VS list()中的列表解析.values_list()list() VS列表理解的一般性讨论已经在其他问题中得到了解释。

TLDR所以我想这是两个因素之间的权衡。

  1. .values_list().all()之间执行时间的明显差异(从我的测试表明我们不能简单地推断出更少的字段被提取导致更快的执行 - 更多调查因此导致的底层django源代码)
  2. 使用列表理解和list()之间的任何差异

在我的测试用例中,我通常发现.all()查询实际上比.values_list()查询更快,但是当也考虑到转换到列表时,.values_list场景总体上需要更少的时间。所以它可能完全取决于场景......

© www.soinside.com 2019 - 2024. All rights reserved.