2014-10-16 17 views
3

在Django中用'__in'过滤查询集的首选方法是什么?Django带'__in'过滤器性能的ORM values_list

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

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

回答

7

这些应该是完全等价的。在Django的底层,将这两个优化为SQL中的子查询。见QuerySet API reference on in

这个查询集将被评估为子查询语句:

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

但是你可以在你的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) 

这可能是在某些情况下更好的性能,例如,当你有几个供应商,但它会完全依赖于你的数据是喜欢什么,你正在使用的数据库。请参阅上面链接中的“性能注意事项”注释。

4

我同意Wilduck。然而几个音符

您可以结合滤波器,这些成一个像这样的:

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

这将给你相同的结果集 - 在单个查询。

第二件事,分析生成的查询,你可以在最后使用.query子句。

实施例:

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

将打印该查询的ORM将被生成来获取结果集。