-
Notifications
You must be signed in to change notification settings - Fork 898
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
Prevents N+1 SQL queries in miq_request_workflow.rb #17354
Prevents N+1 SQL queries in miq_request_workflow.rb #17354
Conversation
The MiqPreloader.preload call was added prior to the usage of `.writable_storages` for the miq_request_workflow.rb. When writable_storages was called, it would make a new call to the database every time for each of the storages, which was not ideal. This change makes it so that the writable_storages method will first check to see if the proper data is already loaded, and if so, just use that. Otherwise, it will do the query as normal. The other change was to change the MiqPreloader.preload to include the `host_storages`, which properly applies the loaded records needed for the changes to the `host` model to work.
`.load_ar_obj` will defer to `.load_ar_objs` when it is passed an array, which will do a `.collect` call to `load_ar_obj` in return. This is a typical N+1, so this change takes the constantize code from `.load_ar_obj` and applies it to the `allowed_hosts` to make a single SQL call to for the needed hosts.
Checked commits NickLaMuro/manageiq@b77f060~...7bc4621 with ruby 2.3.3, rubocop 0.52.1, haml-lint 0.20.0, and yamllint 1.10.0 app/models/miq_request_workflow.rb
app/models/mixins/relationship_mixin.rb
lib/miq_preloader.rb
|
@miq-bot assign @gmcculloug |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@NickLaMuro
I get the assignment to (GM) due to changes in miq_request_workflow
and miq_request_virt_workflow
. I have 1 small comment, but otherwise things look good.
I'm not sure why the changes to relationship_mixin.rb
, relationship.rb
, and miq_preloader.rb
are part of this PR. I think the changes in those 3 files should be viewed by a larger audience.
@@ -1077,7 +1077,9 @@ def get_selected_hosts(src) | |||
elsif src[:host_id] | |||
selected_host(src) | |||
else | |||
load_ar_obj(allowed_hosts) | |||
allowed_hosts.group_by(&:evm_object_class).flat_map do |type, objs| |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@NickLaMuro - do you think there might be a way to add the group_by
behavior into load_ar_obj
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@syncrou Yeah, I was thinking about that. I mostly decided to shy away from that approach since isolating the code to this method would avoid potential risk of an unknown edge case of load_ar_obj
that I was unware of.
That said, if you would prefer me trying to make this code work there, I can see what I can do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@NickLaMuro - I would. Largely because that method is already abstracting out other potential edge cases. It should be easier to test the changes when applied to that method as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this go merged, I am going to address this specific case separately in another PR.
Thanks for the review, I appreciate it!
The main reason is the That said, I agree with your statement that those files feel pretty out of place compared to the rest of the changes. I just figured it made sense to include all of the changes in a single digestible commit instead of splitting things up into two more additional PRs:
Though, it would pad my PR stats a bit more... 🤔 Not opposed to moving that last commit out of this PR and try to integrate that later. That said, I think the last commit has the biggest impact over all in terms of N+1s in this PR. Thoughts? |
I think a larger audience should have access to the |
7bc4621
to
d986cb6
Compare
For posterity, these are the new metrics I was working up after removing the last commit in this PR:
Of note, this doesn't include the changes that I was working on for |
@miq-bot add_label fine/yes, gaprindashvili/yes |
…quest_workflow Prevents N+1 SQL queries in miq_request_workflow.rb (cherry picked from commit 65631b8) https://bugzilla.redhat.com/show_bug.cgi?id=1593798
Fine backport details:
|
…quest_workflow Prevents N+1 SQL queries in miq_request_workflow.rb (cherry picked from commit 65631b8) https://bugzilla.redhat.com/show_bug.cgi?id=1593797
Gaprindashvili backport details:
|
This has 3 different fixes for 3 different N+1's:
.writable_storages
withMiqPreloader
properly.get_selected_hosts
Does a HACK to MiqPreloader to handle polymorphic relationships, and allows the.get_ems_metadata_tree
to properly preload hosts.The hack should be isolated to just this methods that need it, and should work just like the normalMiqPreloader.preload
when there isn't a hash passed in, but it is admittedly pretty gross...Update: The "HACK" has been rebased out and will be done in a separate branch.
Benchmarks
UPDATE: These are outdated metrics. See this comment for more accurate metrics based on the current changes.
The benchmark script used here basically runs the following:
And is targeting a fairly large EMS, with about 600 hosts.
Note: The benchmarks for this change do NOT include the changes from other PRs in the links below. Benchmarks of all changes can be found here.
Links