简体   繁体   English

Django ORM values_list具有'__in'过滤性能

[英]Django ORM values_list with '__in' filter performance

What is the preferred way to filter query set with '__in' in Django? 在Django中使用'__in'过滤查询集的首选方法是什么?

providers = Provider.objects.filter(age__gt=10)
consumers = Consumer.objects.filter(consumer__in=providers)

or 要么

providers_ids = Provider.objects.filter(age__gt=10).values_list('id', flat=True)
consumers = Consumer.objects.filter(consumer__in=providers_ids)

These should be totally equivalent. 这些应该是完全相同的。 Underneath the hood Django will optimize both of these to a subselect query in SQL. 在引擎盖下,Django会将这两者优化为SQL中的子选择查询。 See the QuerySet API reference on in : 请参阅上查询集API参考in

This queryset will be evaluated as subselect statement: 此查询集将作为subselect语句进行评估:

SELECT ... WHERE consumer.id IN (SELECT id FROM ... WHERE _ IN _)

However you can force a lookup based on passing in explicit values for the primary keys by calling list on your values_list , like so: 但是,您可以通过调用values_list上的list来强制执行基于传递主键显式值的查找,如下所示:

providers_ids = list(Provider.objects.filter(age__gt=10).values_list('id', flat=True))
consumers = Consumer.objects.filter(consumer__in=providers_ids)

This could be more performant in some cases, for example, when you have few providers, but it will be totally dependent on what your data is like and what database you're using. 在某些情况下,这可能会更高效,例如,当您的提供程序很少时,它将完全取决于您的数据是什么样的以及您正在使用的数据库。 See the "Performance Considerations" note in the link above. 请参阅上面链接中的“性能注意事项”说明。

I Agree with Wilduck. 我同意Wilduck。 However couple of notes 然而几个笔记

You can combine a filter such as these into one like this: 您可以将这些过滤器组合成如下所示:

consumers = Consumer.objects.filter(consumer__age__gt=10)

This would give you the same result set - in a single query. 这将为您提供相同的结果集 - 在单个查询中。

The second thing, to analyze the generated query, you can use the .query clause at the end. 第二件事,要分析生成的查询,最后可以使用.query子句。

Example: 例:

print Provider.objects.filter(age__gt=10).query

would print the query the ORM would be generating to fetch the resultset. 将打印ORM将生成的查询以获取结果集。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM