Оптимизация запроса к базе данных 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], это сделает запросы обычно намного быстрее.