У меня есть структура модели Django, которая выглядит следующим образом:
# Pre-defined User model
class A(models.Model):
pass
class B(models.Model):
relevant_users = models.ManyToManyField(User)
related_A = models.ForeignKey(A)
И учитывая User
, я хочу быстро сгенерировать набор запросов всех A, привязанных к B, где пользователь находится в relevant_users
«многие ко многим». Я ожидаю много A, но только один или два B на A, с индексацией только на pk.
У меня есть два метода для генерации этого набора запросов, и оба работают:
Метод 1:
Фильтровать объекты с обратным поиском.
queryset = A.objects.filter(B__relevant_users__exact=user)
Метод 2:
Получите список A pks с прямым поиском, затем найдите эти pks в таблице A. (select_related используется, но здесь опущено для ясности)
a_pks = [b.related_A.pk for b in user.b_set.all()]
queryset = A.objects.filter(pk__in=a_pks)
Это эквивалентно? Имеют ли они одинаковую сложность по времени для больших чисел А?
edit: похоже, что способ 2 в некоторых случаях быстрее:
для малонаселенных relevant_users
(в основном пусто):
A: 10000
м1: 0,0014 с
м2: 0,0024 с
A: 100 000
м1: 0,0016 с
м2: 0,0028 с
Для густонаселенных relevant_users
(все B имеют хотя бы одного пользователя):
A: 10000
м1: 0,040 с
м2: 0,019 с
A: 20000
м1: 0,066 с
м2: 0,031 с