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

Remove N+1 caused by question.publishable_results? #107

Open
sauloperez opened this issue Jun 11, 2021 · 0 comments
Open

Remove N+1 caused by question.publishable_results? #107

sauloperez opened this issue Jun 11, 2021 · 0 comments

Comments

@sauloperez
Copy link
Collaborator

https://github.com/coopdevs/decidim-module-action_delegator/blob/1c22b438cbd51afcc7ac4cfb41bc70deacb94f5f/app/views/decidim/action_delegator/admin/consultations/results.html.erb#L40

Is causing a couple N+1. That's because for every question we call Decidim's Question#publishable_results? which in turn calls consultation.finished? and responses.order(votes_count: :desc).

This results in the following logs

Decidim::Consultation Load (0.7ms)  SELECT  "decidim_consultations".* FROM "decidim_consultations" WHERE "decidim_consultations"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]                
  ↳ /home/pau/.rbenv/versions/2.7.3/lib/ruby/gems/2.7.0/bundler/gems/decidim-dd26de389f5a/decidim-consultations/app/models/decidim/consultations/question.rb:79                                 
  Decidim::Consultations::Response Exists (0.7ms)  SELECT  1 AS one FROM "decidim_consultations_responses" WHERE "decidim_consultations_responses"."decidim_consultations_questions_id" = $1 LIM
IT $2  [["decidim_consultations_questions_id", 5], ["LIMIT", 1]]                                                                                                                                
  ↳ /home/pau/.rbenv/versions/2.7.3/lib/ruby/gems/2.7.0/bundler/gems/decidim-dd26de389f5a/decidim-consultations/app/models/decidim/consultations/question.rb:79                                 
  CACHE Decidim::Consultation Load (0.0ms)  SELECT  "decidim_consultations".* FROM "decidim_consultations" WHERE "decidim_consultations"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]          
  ↳ /home/pau/.rbenv/versions/2.7.3/lib/ruby/gems/2.7.0/bundler/gems/decidim-dd26de389f5a/decidim-consultations/app/models/decidim/consultations/question.rb:79                                 
  Decidim::Consultations::Response Exists (1.4ms)  SELECT  1 AS one FROM "decidim_consultations_responses" WHERE "decidim_consultations_responses"."decidim_consultations_questions_id" = $1 LIM
IT $2  [["decidim_consultations_questions_id", 8], ["LIMIT", 1]]                                                                                                                                
  ↳ /home/pau/.rbenv/versions/2.7.3/lib/ruby/gems/2.7.0/bundler/gems/decidim-dd26de389f5a/decidim-consultations/app/models/decidim/consultations/question.rb:79
  CACHE Decidim::Consultation Load (0.0ms)  SELECT  "decidim_consultations".* FROM "decidim_consultations" WHERE "decidim_consultations"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  ↳ /home/pau/.rbenv/versions/2.7.3/lib/ruby/gems/2.7.0/bundler/gems/decidim-dd26de389f5a/decidim-consultations/app/models/decidim/consultations/question.rb:79
  Decidim::Consultations::Response Exists (0.8ms)  SELECT  1 AS one FROM "decidim_consultations_responses" WHERE "decidim_consultations_responses"."decidim_consultations_questions_id" = $1 LIM
IT $2  [["decidim_consultations_questions_id", 6], ["LIMIT", 1]]
  ↳ /home/pau/.rbenv/versions/2.7.3/lib/ruby/gems/2.7.0/bundler/gems/decidim-dd26de389f5a/decidim-consultations/app/models/decidim/consultations/question.rb:79
  CACHE Decidim::Consultation Load (0.0ms)  SELECT  "decidim_consultations".* FROM "decidim_consultations" WHERE "decidim_consultations"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  ↳ /home/pau/.rbenv/versions/2.7.3/lib/ruby/gems/2.7.0/bundler/gems/decidim-dd26de389f5a/decidim-consultations/app/models/decidim/consultations/question.rb:79
  Decidim::Consultations::Response Exists (0.8ms)  SELECT  1 AS one FROM "decidim_consultations_responses" WHERE "decidim_consultations_responses"."decidim_consultations_questions_id" = $1 LIM
IT $2  [["decidim_consultations_questions_id", 7], ["LIMIT", 1]]
  ↳ /home/pau/.rbenv/versions/2.7.3/lib/ruby/gems/2.7.0/bundler/gems/decidim-dd26de389f5a/decidim-consultations/app/models/decidim/consultations/question.rb:79
  Rendered /home/pau/dev/decidim-module-action_delegator/app/views/decidim/action_delegator/admin/consultations/results.html.erb within layouts/decidim/admin/consultation (20.5ms)
  Rendered /home/pau/.rbenv/versions/2.7.3/lib/ruby/gems/2.7.0/bundler/gems/decidim-dd26de389f5a/decidim-core/app/views/layouts/decidim/_organization_colors.html.erb (0.3ms)
  Decidim::DecidimAwesome::AwesomeConfig Load (1.0ms)  SELECT "decidim_awesome_config".* FROM "decidim_awesome_config" WHERE "decidim_awesome_config"."decidim_organization_id" = $1  [["decidim
_organization_id", 1]]

Proposed solution

The solution is to eager load both the consultation and the responses as part of the query performed from https://github.com/coopdevs/decidim-module-action_delegator/pull/106/files#diff-3e9e68c68f5a828e175f3957f398f80a95e20967f772bfe6be7aba260c01db36R59-R70. At this point, that method should probably be renamed to #results_query. It reaches out to many more tables than just questions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant