Оптимизация запроса к базе данных Django

Какой способ лучше? и почему? queryset = Tariff.objects.filter(user=user).order_by('-created_at').first() или queryset = Tariff.objects.filter(user=user).order_by('created_at').last()

Вам нужно получить самую новую запись из базы данных, какой способ лучше и быстрее?

The two are equivalent. Indeed, if we look at the implementation [GitHub] of the .last() method [Django-doc]:

def last(self):
    """Return the last object of a query or None if no match is found."""
    if self.ordered:
        queryset = self.reverse()
    else:
        self._check_ordering_first_last_queryset_aggregation(method="last")
        queryset = self.order_by("-pk")
    for obj in queryset[:1]:
        return obj

Это изменит порядок следования запроса, так что если вы сделали ORDER BY some_column ASC, то теперь будет показано ORDER BY some_column DESC. Таким образом, оба варианта приведут к одному и тому же запросу.

Заметим, однако, что:

queryset = Tariff.objects.filter(user=user).order_by('-created_at').first()

является не объектом QuerySet, это Tariff объект, или None, если такой объект отсутствует.

Вы можете написать это немного короче, используя:

tariff = Tariff.objects.filter(user=user).latest('created_at')

, которые вызовут Tariff.DoesNotExist исключение, если для данного пользователя не существует Tariff объекта, но все они выдадут один и тот же SQL-запрос.

Если вы еще не сделали этого, вы можете добавить индекс базы данных на поле created_at с помощью db_index=True [Django-doc], это сделает запросы обычно намного быстрее.

Вернуться на верх