Closed taobojlen closed 2 weeks ago
Looks like the issue is in the optimizer, on this line:
qs = qs.only(*(only_set | select_related_only_set))
Before this line, evaluating the queryset executes 1 SELECT
query. After this line, evaluating it executes 3 queries. I thought this may be a Django bug but I cannot reproduce it in my own Django project.
The extra queries could come from something calling __repr__
on each item in the queryset. I think so because of the LIMIT 21
clause in the SQL queries, and this code: https://github.com/django/django/blob/53719d6b5b745dd99b1ab9315afb242f706ebbf1/django/db/models/query.py#L376
Alternatively, it's because something is calling .get()
on each item in the queryset: https://github.com/django/django/blob/53719d6b5b745dd99b1ab9315afb242f706ebbf1/django/db/models/query.py#L643
I did some tests here and to fix this issue, I would cause others :(
To properly resolve this I need to first resolve https://github.com/strawberry-graphql/strawberry-django/issues/337
Describe the Bug
When the optimizer is enabled with the
only
extension, resolvers like the following lead to an N+1:Resolving this Relay connection leads to the following SQL queries:
Additional Context
You can reproduce this issue by adding the above resolver to
MilestoneType
intests/projects/schema.py
, then use the following test:I've done a bit of debugging, and I can see that the N+1 queries are executed in
DjangoOptimizerExtension.resolve()
. Specifically, this line:This line executes three queries:
I'm continuing to debug to isolate where these queries are coming from, and happy to open a PR once I fix it! But if anyone has a hunch or any pointers, let me know.
Upvote & Fund