Skip to content
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

Resolve N+1 on Attachments in Search Results #1881

Merged
merged 3 commits into from
Sep 18, 2020

Conversation

mbarnett
Copy link
Contributor

@mbarnett mbarnett commented Sep 18, 2020

Context

With the switch from Fedora to PostgreSQL, we're increasing pressure on the DB server, and consequently turning up some old inefficiencies that can now be addressed.

Previously, search results involved making:

  1. one Solr query containing all of the data needed to render the results minus information about the attachments
  2. 10 queries to Solr to fetch the attachments for the 10 results on the page.

Now, we are making:

  1. one Solr query, giving us the IDs of the resulting model instances
  2. 10 queries for the model instances
  3. 10*N more queries for the model instances' attachments, where N is the number of attachments each instance has

This is excessive.

This PR aims to address point 3 (point 2 may be addressed separately at some point as per

# TODO: This is inefficient and we should look at batching up IDs
but note the significant challenge here is that not all Solr results will necessarily come from the same DB table, so batching it up into a single query is likely impossible unless we unify Item and Thesis)

A complicating factor here is that the ActiveStorage API names the eager-load scope according to the attached model so, for instance, Item(and Thesis), which has_many_attached :files, has an eager-loading scope of with_attached_files, whereas Community, which has_one_attached :logo, has an eager-loading scope of with_attached_logo. And Collection has no eager-loading scope at all, because it lacks any attachments.

DeferredFacetedSolrQuery potentially deals with results containing all of the above models at runtime, with no knowledge of which scope to call when making a query for the record in the result:

arclass = res['has_model_ssim'].first.sub(/^Ar/, '').constantize
arclass.find(res['id'])

What's New

We introduce two new Class methods in the Depositable superclass (which all Solr-searchable models must inherit from).

  1. A protected method, self.eager_attachment_scope, which should return a model-specific call to the correct scope for the kind of attachment specific to the model (so eg. Item returns self. with_attached_files). By default this method blows up noisily when called, to force us to remember to override it correctly in all subclasses. Models like Collection simply make this method a no-op by choosing to return self.

  2. A public method, self.with_eagerly_loaded_attachments, which simply gives the models' client code a nicer DSLy method for accessing the scope.

DeferredFacetedSolrQuery is then altered to use the scope on all classes during reification of search results.

(unrelatedly, I also shifted the methods around in Item and Thesis to group all instance methods and class methods together, because they were kind of a random mess)

@ualbertalib-bot
Copy link

ualbertalib-bot commented Sep 18, 2020

1 Warning
⚠️ There are code changes, but no corresponding tests. Please include tests if this PR introduces any modifications in behavior.

Generated by 🚫 Danger

Copy link
Contributor

@murny murny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me 👍. Nice work.

Might be nice to use bullet gem (https://github.com/flyerhzm/bullet) to help us discover these in the future since we now on ActiveRecord 🤔

@mbarnett
Copy link
Contributor Author

Good idea! I'll take that for a spin locally and try it out.

@mbarnett mbarnett merged commit 39ccf00 into integration_postmigration Sep 18, 2020
@mbarnett mbarnett deleted the msb/remove_attachment_n_plus_one branch September 18, 2020 21:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants