Является ли использование любого с QuerySet неоптимальным?
Много раз возникает необходимость проверить, есть ли хотя бы один элемент внутри QuerySet. В основном я использую exists:
if queryset.exists():
...
Однако я видел коллег, использующих функцию python any:
if any(queryset):
...
Является ли использование функции python any неоптимальным?
Моя интуиция подсказывает мне, что это дилемма, аналогичная дилемме между использованием count и len: any будет выполнять итерацию через QuerySet и, следовательно, должен будет оценить его. В случае, когда мы будем использовать элементы QuerySet, это не создаст никаких замедлений. Однако, если нам нужно просто проверить, существуют ли части данных, удовлетворяющие запросу, это может загрузить данные, которые нам не нужны.
Является ли использование функции any в python неоптимальным?
Наиболее питоническим способом было бы:
if queryset:
# …
И действительно, QuerySet имеет истинность True если содержит хотя бы один элемент, и False иначе.
В случае, если вы позже захотите перечислить по кверисету (например, с помощью цикла for), он будет загружать элементы в кэш, если вы проверите его истинность, например:
if queryset:
for item in queryset:
# …
будет сделан только один запрос к базе данных: один, который извлечет все элементы, когда вы проверите if queryset, а затем позже вы сможете повторно использовать этот кэш, не делая второго запроса.
В случае, если вы не используете queryset позже в процессе, тогда вы можете работать с .exists() [Django-doc]: это позволит не загружать записи в память, а только делать запрос, чтобы проверить, существует ли хотя бы одна такая запись, это, таким образом, менее затратно с точки зрения пропускной способности между приложением и базой данных. Однако если вам придется использовать набор запросов позже, использование .exists() является не хорошей идеей, так как в этом случае мы делаем два запроса.
Использование any(queryset), однако, не имеет смысла: вы можете проверить, содержит ли кверисет элементы, по его истинности, поэтому использование any() обычно только делает эту проверку слегка менее эффективной.