以下是我的方案:
城市-->摄影师
我正在尝试获取至少有一名摄影师的城市列表,并返回这些城市的摄影师计数。
下面是我正在使用的查询集:
City.objects.annotate(photographer_count=aggregates.Count('photographers')).filter(photographer_count__gt=0).order_by('-photographer_count')这也完全符合我的预期,除了出于某些原因,Django选择在城市/摄影师之间使用左外部连接。如果我抓取SQL文本并简单地将“左外部”更改为“内部”,则查询时间从大约11秒增加到200ms,结果相同。
我试着在注解前面放一个过滤器,以提示Django它应该是内部连接,但这不起作用。
我可以对此执行任何Django查询伏都教来获得内连接吗?我意识到我可以直接使用SQL,但我更喜欢使用ORM。
发布于 2017-08-08 09:21:17
默认情况下,会生成一个LEFT JOIN,以便Django即使在没有摄影师的城市也能得到行。如果您知道您不需要这些,这里有一个技巧可以强制Django生成一个INNER JOIN
City.objects.filter(
photographer__isnull=False
).annotate(
photographer_count=aggregates.Count('photographers')
).filter(
photographer_count__gt=0
).order_by(
'-photographer_count'
)具体地说,第一个过滤器告诉Django INNER JOIN是安全。它必须在annotate()调用之前出现。
发布于 2012-07-24 07:52:56
您通常无法对Django执行的查询和连接进行这种级别的控制。
Django没有做真正聪明的事情,比如注意到过滤条件意味着你可以在这一点上摆脱内部连接-它必须产生在一般情况下正确的查询,在这种情况下,据我所知,这意味着一个左外部连接。
因此,您可能需要原始SQL。
https://stackoverflow.com/questions/11619693
复制相似问题