在测试我的 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 调用会返回至少没有一个错误结果的任何发现。在查询单个值的非空字段时,它们可以互换,但并非在所有情况下都可以互换。
