Я пытаюсь оптимизировать некоторый код Django, и у меня есть два похожих подхода, которые выполняют разные. Вот некоторые примеры моделей:django filtering vs python filtering with prefetched objects
class A(models.Model):
name = models.CharField(max_length=100)
class B(models.Model):
name = models.CharField(max_length=100)
a = models.ForeignKey(A)
c = models.ForeignKey(C)
class C(models.Model):
name = models.CharField(max_length=100)
Для каждого A
объекта, я хотел бы, чтобы перебрать подмножество его входящих B
«с, отфильтрованный по их стоимости c
. Простой:
for a in A.objects.all() :
for b in a.B_set.filter(c__name='some_val') :
print a.name, b.name, c.name
Проблема с этим состоит в том, что существует новый поиск в базе данных для каждого a
значения итерации.
Похоже, что решение состоит в предварительной выборке значений c, которые будут подаваться в фильтр.
qs_A = A.objects.all().prefetch_related('B_set__c')
Теперь рассмотрим следующие два фильтра подходов:
# Django filter
for a in qs_A :
for b in a.B_set.filter(c__name='some_val') :
print a.name, b.name, n.name
# Python filter
for a in qs_A :
for b in filter(lambda b: b.c.name == 'some_val', a.B_set.all()):
print a.name, b.name, c.name
С данными я использую, то Джанго фильтр составляет 48 больше запросов SQL, чем питон фильтра (на 12-элементной qs_A
результата задавать). Это заставляет меня поверить, что фильтр django не использует предварительно загруженные таблицы.
Может ли кто-нибудь объяснить, что произошло?
Возможно, можно применить фильтр во время предварительной выборки?