Dataloader
Due to the flexibility of GraphQL, when we load the associated objects of a certain object, we usually need to execute multiple queries. This leads to the well-known N+1 query problem. To solve this problem, we can use DataLoader.
DataLoader
can combine multiple requests into one request, thus reducing the number of database queries. It can also cache query results to avoid duplicate queries.
Examples
Table Definition
Consider that we have two tables, users
and posts
, where posts
is associated with the id
of users
through posts.authorId
:
Data Seeding
Let's use drizzle-seed to populate some data into the database:
Create a Resolver
Let's write a simple resolver for the User
object:
In the above code, we defined a user resolver, which includes:
users
query: used to get all usersposts
field: used to get all posts of the corresponding user
Here is an example query that will return the information of all users and their corresponding posts:
This query will query the posts for each user separately. We populated 20 users in the database in the previous step, so this query will cause 20 queries to the posts
table.
This is obviously a very inefficient way. Let's see how to use DataLoader to reduce the number of queries.
Using DataLoader
Next, we will use DataLoader to optimize our query.
In the above code, we use field().load()
to enable batch data loading. Behind the scenes, this will use DataLoader
to batch load data.
Inside load()
, we implement batch data loading through the following steps:
- Use the
in
operation to get all the posts of the currently loaded users from theposts
table at once; - Use
Map.groupBy()
to group the list of posts by the author ID; - Map the list of users to the list of posts in order. If a user has no posts, return an empty array.
In this way, we combine the original 20 queries into 1 query, thus achieving performance optimization.
It is necessary to ensure that the order of the returned array of the query function is consistent with the order of the IDs
array. DataLoader
relies on this order to correctly merge the results.