Details
-
Improvement
-
Status: Done
-
Minor
-
Resolution: Done
-
None
-
None
-
None
Description
Avoid N + 1 queries in GraphQL
Let's look at the query below.
query { User(id: 1) { name Like(limit: 5) { # fetch edge (has sourceVertex id == 1) Movie { # fetch vertex every edges, N + 1 query for fetch vertex info title } } } }
The query retrieves the User(id: 1)'s name and 10 movie titles the user likes.
In this case, the query that occurs internally in S2Graph is as follows
- Fetch a vertex to resolving the 'name' field (1 IO)
- fetch 5 edges to resolving the 'Like' field (1 IO)
- fetch 5 vertices for each Edge to resolving the movie 'title' (10 IO)
Assuming that the Movie ID of the edge returned in step.2 is [e1..e5], the query executed to get Movie title is as follows.
getVertices(e1) getVertices(e2) getVertices(e3) getVertices(e4) getVertices(e5)
Retrieving every vertices one-by-one would be very inefficient
In this case, you can query the Movie Vertex of the edge by collecting 5 IDs without querying each one.
ex) getVertices([e1, e2, e3, e4, e5])
Which of these two approaches Whether it is more efficient depends on the internal implementation of S2Graph.
But here we are considering the GraphQL implementation.
Follow the instructions below to resolve the issue.
Reference:
http://sangria-graphql.org/learn/#deferred-value-resolution
https://github.com/sangria-graphql/sangria/issues/63
Attachments
Issue Links
- links to