strawberry-django
strawberry-django copied to clipboard
Avoid unnecessary query for edges when only fetching totalCount in connection
Feature Request Type
- [ ] Core functionality
- [x] Alteration (enhancement/optimization) of existing feature(s)
- [x] New behavior
Description
When I was analyzing the SQL queries using the debug toolbar, I found that Django creates two queries for such a connection query. However, one of the queries is unnecessary.
# Query for a connection
query {
books {
totalCount
}
}
# Query for edges (unnecessary)
SELECT books_book.id, books_book.title, books_book.author, books_book.price
FROM books_book
LIMIT 101;
# Query for totalCount
SELECT COUNT(*) AS "__count"
FROM "books_book";
The first SQL query is created when the strawberry connection resolver (not strawberry_django) iterates over the queryset to create edges. The creation of edges will always happen even if edges are not requested in the query. Because a Connection
, which includes edges and page_info, is always created first and then used as a source to construct its sub_fields such as edges, totalCount, and __typename.
# strawberry/relay/types.py
@classmethod
def resolve_connection(...)
...
edges = [
edge_class.resolve_edge(
cls.resolve_node(v, info=info, **kwargs),
cursor=start + i,
)
for i, v in enumerate(iterator) # SQL query is triggered here
]
...
I saw there is a connection resolver for ListConnectionWithTotalCount. However, it is just a wrapper around the connection resolver in strawberry. Should we create a customized connection resolver for Django, which checks the request fields before doing operations that trigger SQL queries? For example, we can check if the edges
is in the query before creating edges in the resolver.
selections = {s.name for s in info.selected_fields[0].selections}
edges = []
if "edges" in selections:
edges = [
edge_class.resolve_edge(
cls.resolve_node(v, info=info, **kwargs),
cursor=start + i,
)
for i, v in enumerate(iterator)
]
If this is a valid idea. I can create a PR for this optimization. Thanks for your time and consideration.
Upvote & Fund
- We're using Polar.sh so you can upvote and help fund this issue.
- We receive the funding once the issue is completed & confirmed by you.
- Thank you in advance for helping prioritize & fund our backlog.
Hey @Carlisle345748,
Hrm, that's interesting. It is actually the first time I see someone only wanting to query the totalCount
and not the edges
=P
I do understand your use case, and I do welcome you to create a PR to optimize this :)
Feel free to ping me on discord if you need any help with the development
is a patch available somewhere for this one ?