我注意到,在Django的遗留版本中,一个曾经很快的查询现在在4.0.8中慢了很多.
有一个相当大的表,带有一个FK‘标记’和一个附加了索引的布尔‘标记’.以下查询可能会合理地返回数万行.
在我的代码库中,有一个查询,如
MyModel.objects.filter(marker_id=123, flag=False).count()
个
在Django Debug工具栏中(在我判断str(qs.query)
的时候,在Shell中也是如此),它现在解析为以下SQL语法:
SELECT ••• FROM `myapp_mymodel` WHERE (`myapp_mymodel`.`marker_id` = 123 AND NOT `myapp_mymodel`.`flag`)
个
在极端情况下,该查询大约运行20秒.同时,在传统的Django版本(1.11+)中,相同的查询变成以下SQL:
SELECT ••• FROM `myapp_mymodel` WHERE (`myapp_mymodel`.`marker_id` = 123 AND `myapp_mymodel`.`flag` = 0)
个
这是可行的,因为表模式包含作为TINYINT(1)的‘FLAG’,但最重要的是,它的工作速度提高了much--返回不到一秒.
EDIT:我要求SQL SERVER解释这两个查询,在后一个(较快的)查询中显示为潜在关键字的‘FLAG’有所不同,而在较慢的查询中没有.这与this answer一致,说明MySQL需要查看与某个值的比较才能使用索引.因此,主要问题变成了,我如何强制使用已经存在的索引的语法?
END EDIT个
Original questions:Why is the difference in ORM-to-SQL translation, and where can I find the code responsible (I have checked db.backends.mysql to no avail, or failed to recognize the culprit)? Is there a way to hint to Django that I'd much prefer the equals-zero behaviour?
到目前为止,我看到的唯一解决办法是使用原始SQL查询.如果可能的话,我宁愿避免这种情况.