在测试我的 Django 应用程序时,当使用特定的 filter() 时,我遇到了特定查询的性能问题。问题已解决,但我不明白为什么。
我正在根据 3 个条件过滤 QuerySet。当一次包括它们时,我得到了预期数量的结果。当将其中一个子句移动到它自己的 filter() 调用时,生成的 QuerySet 比它应该的大得多,并且充满了看似重复的条目。
请参见下面的说明。将 result__is_false=False
子句移动到它自己的 filter() 会导致结果 QuerySet 的巨大扩展。
>>> Finding.objects.filter(project=1, result__scan_session__is_enabled=True,\
result__is_false=False).count()
3566
>>> Finding.objects.filter(project=1, result__scan_session__is_enabled=True)\
.filter(result__is_false=False).count()
10050380
问题是我需要有条件地应用有问题的过滤器,而不是每次都应用。我通过将 filter() 例程转换为 exclude() 例程解决了这个问题,如下所示:
>>> Finding.objects.filter(project=1, result__scan_session__is_enabled=True)\
.exclude(result__is_false=True).count()
3566
这似乎成功了!
虽然我很高兴这有效,但我不明白两件事:
1) 为什么解释 filter() 和 exclude() 的帖子似乎暗示它们可以被视为相等但相反,当基于上面的示例时,情况并非总是如此。
2) 为什么将 result__is_false=False
子句移动到它自己的 filter() 首先导致结果的巨大跳跃。
有没有人对其中任何一个有任何见解?
最佳答案
这两个看起来都像是连续 filter
调用如何处理多值关系的预期结果。 docs详细解释,举例说明:
Everything inside a single filter() call is applied simultaneously to filter out items matching all those requirements. Successive filter() calls further restrict the set of objects, but for multi-valued relations, they apply to any object linked to the primary model, not necessarily those objects that were selected by an earlier filter() call.
因此,您的第二个 filter
调用会返回任何 Finding
,其中至少有一个非假结果。 exclude
调用会返回至少没有一个错误结果的任何发现。在查询单个值的非空字段时,它们可以互换,但并非在所有情况下都可以互换。
关于python - Django filter() 增加结果查询集而不是减少,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43724611/