[GraphQL] Aim to reduce N+1 queries
In our GraphQL we could make better use of the Query to avoid N+1 queries. The key to this is making use of lookahead
Example
The following query shows where we could avoid extra queries:
query {
project(fullPath: "gitlab-org/gitlab") {
mergeRequests(first: 10) {
author {
username
}
assignees {
nodes { username }
}
}
}
}
In this query, we will execute it as follows (simplified)
- find the project by full path (1 query)
- find the first 10 merge requests (1 query)
- for each merge request:
- find the author (1 query)
- find the assignees (1 query)
For a total of 22 queries.
The optimal solution would be something like:
- find the project by full path (1 query)
- find the first 10 merge requests (1 query)
- Find the union of assignees and author for the MRs (1 query)
But the low hanging fruit is to use the fact that the query tells us up-front
that we will need author
and assignees
and use #preload(:author, :assignees)
to reduce this to 4 queries, and eliminate the N + 1
complexity.
Very few (if any) of our resolvers perform this kind of lookahead optimization, but it could have a significant ~performance impact, especially for large collections that we expect to be retrieved, such as merge requests, issues, pipeline jobs, etc.