-
Notifications
You must be signed in to change notification settings - Fork 251
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
reuseFragments in QueryPlannerConfig not working as expected #2457
Comments
@trevor-scheer / @pcmanus The issue I found is that query fragment as seen in the code below is used only if the selection set match exactly.
However, there are scenarios where the query fragments a portion of the type and utilizes it in multiple places. Therefore, I have made some modifications to the aforementioned code.
My proposal is to automatically create a fragment for a selection set that did not exactly match any of the request defined fragments. I am also adding an option to QueryPlannerConfig.experimental_autoFragmentQuery to enable it.
|
@trevor-scheer / @pcmanus
|
I generally agree that we can and should improve our handling of fragments. In particular, there is cases where we ought to be able to reuse existing fragments but we don't and it's been on my todo list to better identify why and see if we can improve it. That said, there is always going to be limitations on re-using the fragments of the original query, since only fragments whose full selection goes the same subgraph can ever be reused this way. So I agree we do need an additional strategy to automatic generate fragments to optimise repetitive subgraph queries. Looking quickly at the PR, the strategy appears to check for re-used full sub-selections for each composite field/inline fragments. I'll admit that in a perfect world I'd love to be able to come up with a more fine-grained strategy, something that can handle sub-selections that only partly match, but it's certainly more involved, so starting experimenting with your strategy make sense. It clearly seem to help a lot in your case, though I'm curious to see how common such improvements is with this strategy, and it also looks like the strategy may be quite costly in term of query planning time so I'd like to try to better quantify the tradeoffs. That said, as the PR adds this as an opt-in and experimental feature, those questions don't necessarily have to block getting this in. Long story short, I'll try to have a closer look at reviewing the PR soon (new week hopefully). |
@pcmanus I comprehended that dealing with sub-selections that partially match the selection set can be advantageous. However, this approach did not yield complete optimization as certain query fragments were already expanded before calling the optimization process, resulting in a lack of accuracy for some input fragments. In the most recent update, I have incorporated code to address sub-selections and automatically fragmentize them if the feature is enabled. The modifications I made to the tests in operation.test.ts will demonstrate the advantages
Please let me know your thoughts |
were you able review the code, any suggestions ? |
@AneethAnand: very sorry I wasn't able to get to this earlier. I did just now leave some comment, though one thing that happened since my last comment is #2497: the code for reusing existing fragments is a lot more capable now, and this may help the initial issue that this issue was created for (meaning: yes, That said, as mentioned previously, there is still room for creating new fragments when none can genuinely be reused, so I'm still ok with your PR as an experiment. But the code from #2497 conflicts quite a bit with said PR so it will need a rebase, and some of the things in the current PR are no longer necessary (because #2497 handles them). As I mentioned in the PR, I'm happy to help with the rebase if necessary. |
@pcmanus I will incorporate your comments and reply. Thanks! |
@pcmanus I really need your help rebasing my changes with yours. I am not sure what the following function does. As you know I am trying to auto fragment, if we dont find a matching fragment. Not sure how do I differentiate between if the current selection set has a matching fragment or not.
Can you please help with the rebase? |
@pcmanus With all your latest changes for "reUse" fragments , we still see query being expanded, though it has improved to some extent. For example like I mentioned above 1000 lines of incoming query is now 7K lines in the Query Plan Now that I am not sure how can I apply auto fragment and make it efficient like I did before with your new changes. I believe you have moved from dfs to bfs based approach not sure when can I apply auto fragment. Can you please help me here with some suggestions? |
Problem statement
The issue is exactly what has been explained here : Gateway(experimental): compress downstream requests via generated fragments apollo-server#3791
For large queries (esp. ones that leverage many nested fragments), queries to subgraph services blows up astronomically because the gateway's query plan expands the query request. Above all since we enable APQ for the downstream request, we are repeatedly creating SHA for this expanded query string
Following is the Query Plan, which uses some of the fragments (not all) from the query but still number of lines 20523 for 2000 lines of query
Existing Solution
QueryPlannerConfig.reuseQueryFragments or experimental_autoFragmentization did not help.
Code
"addTypenameFieldForAbstractTypesInNamedFragments" -- adds typename not to the fragment but on the selection set.
Possible Solution
After I read through the code, I added "__typename" field to all fragments and then I saw reduction in the downstream query
From 20K to 1K
I would like to know your thoughts on how adding __typename reduces the subgraph request query?
Can it be automated in the queryPlan and then later prune those fields out from the result?
If you can give me few pointers I would also be happy to contribute back
The text was updated successfully, but these errors were encountered: