-
-
Notifications
You must be signed in to change notification settings - Fork 144
Open
Labels
bugSomething isn't workingSomething isn't working
Description
Describe the Bug
In a nested ListConnectionWithTotalCount
, if the child has total_count
in the query, if there is a parent node with no related child nodes, there is a queryset.count()
triggered. This leads to N+1 queries like scenario if very few parent nodes have child nodes.
strawberry-django/strawberry_django/pagination.py
Lines 269 to 298 in 269954c
def get_total_count(queryset: QuerySet) -> int: | |
"""Get the total count of a queryset. | |
Try to get the total count from the queryset cache, if it's optimized by | |
prefetching. Otherwise, fallback to the `QuerySet.count()` method. | |
""" | |
from strawberry_django.optimizer import is_optimized_by_prefetching | |
if is_optimized_by_prefetching(queryset): | |
results = queryset._result_cache # type: ignore | |
if results: | |
try: | |
return results[0]._strawberry_total_count | |
except AttributeError: | |
warnings.warn( | |
( | |
"Pagination annotations not found, falling back to QuerySet resolution. " | |
"This might cause n+1 issues..." | |
), | |
RuntimeWarning, | |
stacklevel=2, | |
) | |
# If we have no results, we can't get the total count from the cache. | |
# In this case we will remove the pagination filter to be able to `.count()` | |
# the whole queryset with its original filters. | |
queryset = remove_window_pagination(queryset) | |
return queryset.count() |
Instead, if the queryset is optimized (is_optimized_by_prefetching
is True
) and there is no offset / limit mentioned then it should just return 0 assuming no nodes were found, calling the count()
method only for unoptimized querysets.
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working