-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Several SQL queries for each related item instead of one aggregated query #6035
Comments
I believe this is fixed in the current builds. Not sure where the "basic" example ended up; I tested against the Running a GraphQL query like yours: query {
authors {
id
name
posts { id title }
}
} Now logs:
If you format that last query you'll see it's selecting multiple posts: SELECT `main`.`Post`.`id`, `main`.`Post`.`title`, `main`.`Post`.`status`, `main`.`Post`.`content`, `main`.`Post`.`publishDate`, `main`.`Post`.`author`
FROM `main`.`Post`
WHERE (`main`.`Post`.`id`) IN (
SELECT `t0`.`id`
FROM `main`.`Post` AS `t0`
INNER JOIN `main`.`Author` AS `j0` ON (`j0`.`id`) = (`t0`.`author`)
WHERE (`j0`.`id` = ? AND `t0`.`id` IS NOT NULL)
)
LIMIT ?
OFFSET ? So one query for the Let me know if you're still seeing an issue. |
Yes, this looks good when there is only one item in relation, but if there are many items, the problem is still here with current fresh version (commit id 7a7f3f6). How to reproduce with
query {
posts {
id, title
author { id, name }
}
} and see the several queries in result:
There are 6 separate queries for each related author, even having 2 authors in database! Ideally here must be two queries (first - grab all posts and gather relation ids, second - grab authors, mentioned in posts relations), or at least three queries (all posts, and one query per each unique author id). |
The source of this issue is the "N+1" problem, that is unsolved yet in Keystone's GraphQL implementation. So maybe reopen this issue to keep this problem active? And this happens in many GraphQL based API, here are some articles with more detailed description and possible solutions for it:
|
Ah, you're right, my test case was flawed. I've reproduced this now but still surprised this is occurring. We lean heavily on Prisma for query building and it uses a data loaders to avoid N+1 query behaviour. I guess Keystone must be doing something that inadvertently prevents that approach from working. Thanks @MurzNN, I'll put this on the list to investigate. |
Ok, I've talked this though with @timleslie (apparently you and him have been chatting recently too). My current understanding is that, yes, Prisma does proactively apply a data loader pattern to avoid N+1 problems but only does so when it's really obvious that it can (only There may be some low hanging fruit here whereby, maybe we can only call Regardless, you shouldn't be relying on Keystone to always build optimal queries. If you have complex queries that are used regularly in your main frontend, you're probably better moving to custom mutations that do exactly what's needed. The CRUD schema Keystone provides is intended to support the Admin UI and as a starting point for general app dev. |
Partial fix underway in #6639 🥳 |
Hey @MurzNN, this should now be fixed by #6639. Would love your confirmation. Note the fix only helps when you're resolving a relationship "many-to-one", as in your example. Ie. when the query builder has the foreign key value and is looking that up in the parent table. There are still cases where N+1 behaviour will be observed, eg. other relationship types, the other query "direction" or if filter-based access control is being applied. Neither Prisma or Keystone is setup to optimally resolve these types of query. Regardless, I believe this specific issue is can be closed. |
Hi, I am running into this issue when using filter-based access control. So I do have n+1 queries. I am wondering whether there is a better way of handling this. E.g. maybe do the filtering on the loaded elements (post query). Right now I do have a similar filter access query
This leads to It would be cool to be able to add a hook that could perform the filtering on the relation result set (e.g. load all the foreign related objects, and then filter out the ones that wont match). I am guessing that keystone is waiting for prisma to pick up the issue (see prisma/prisma#1477) however, it does not appear that this will happen anytime soon. |
Hmm, maybe I am in luck, this look like it would do the trick: #8000 |
The PR number says that you're in luck! 😉🤣 |
I'm seeing this behaviour when doing simple queries again, not sure if it's a regression or an issue that never got solved. |
Bug report
Describe the bug
When executing very simple GraphQL query with querying data from one relationship field, Keystone executes separate query for each relation, instead of one aggregated query with list of needed ids
To Reproduce
enableLogging: true
.Problems:
id
andauthor
for query results?Those problems give large performance degradation on databases with many items!
Expected behavior
System information
Keystone version: 21.0.2
The text was updated successfully, but these errors were encountered: