Skip to content

Milestone burndown chart has an N+1 in checking for weights

Visiting a page like %12.5 generates almost 3,000 SQL queries for me. Some of these are due to #33638 (closed).

Some of the others are due to weight checks. I see repeated queries like these:

SELECT "namespaces".* FROM "namespaces" WHERE "namespaces"."id" = 2750817 LIMIT 1 
SELECT "projects".* FROM "projects" WHERE "projects"."id" = 278964 LIMIT 1 

With backtraces like:

[
  "ee/app/models/ee/issue.rb:78:in `supports_weight?'",
  "ee/app/models/ee/issue.rb:74:in `weight'",
  "ee/app/models/burndown.rb:84:in `transformed_create_event_for'",
  "ee/app/models/burndown.rb:54:in `burndown_events_for'",
  "ee/app/models/burndown.rb:48:in `block in burndown_events'",
  "ee/app/models/burndown.rb:48:in `map'",
  "ee/app/models/burndown.rb:48:in `burndown_events'",
  "ee/app/models/burndown.rb:29:in `empty?'",
  "ee/app/helpers/ee/milestones_helper.rb:30:in `data_warning_for'",
  "ee/app/views/shared/milestones/_burndown.html.haml:3:in `_ee_app_views_shared_milestones__burndown_html_haml___3373213837572403095_70136622953600'",
  "app/helpers/application_helper.rb:10:in `render_if_exists'",
  "app/views/shared/milestones/_top.html.haml:56:in `_app_views_shared_milestones__top_html_haml___2629497905139223102_70136621428040'",
  "app/views/groups/milestones/show.html.haml:2:in `_app_views_groups_milestones_show_html_haml___2379218561344713234_70136621019980'",
  "app/controllers/application_controller.rb:123:in `render'",
  "ee/lib/gitlab/ip_address_state.rb:10:in `with'",
  "ee/app/controllers/ee/application_controller.rb:46:in `set_current_ip_address'",
  "lib/gitlab/session.rb:11:in `with_session'",
  "app/controllers/application_controller.rb:461:in `set_session_storage'",
  "app/controllers/application_controller.rb:455:in `set_locale'",
  "ee/lib/omni_auth/strategies/group_saml.rb:39:in `other_phase'",
  "ee/lib/gitlab/jira/middleware.rb:19:in `call'"
]

And:

[
  "ee/app/models/ee/project.rb:681:in `load_licensed_feature_available'",
  "ee/app/models/ee/project.rb:671:in `block (2 levels) in licensed_feature_available?'",
  "ee/app/models/ee/project.rb:675:in `licensed_feature_available?'",
  "ee/app/models/ee/project.rb:280:in `feature_available?'",
  "ee/app/models/ee/issue.rb:78:in `supports_weight?'",
  "ee/app/models/ee/issue.rb:74:in `weight'",
  "ee/app/models/burndown.rb:84:in `transformed_create_event_for'",
  "ee/app/models/burndown.rb:54:in `burndown_events_for'",
  "ee/app/models/burndown.rb:48:in `block in burndown_events'",
  "ee/app/models/burndown.rb:48:in `map'",
  "ee/app/models/burndown.rb:48:in `burndown_events'",
  "ee/app/models/burndown.rb:29:in `empty?'",
  "ee/app/helpers/ee/milestones_helper.rb:30:in `data_warning_for'",
  "ee/app/views/shared/milestones/_burndown.html.haml:3:in `_ee_app_views_shared_milestones__burndown_html_haml___3373213837572403095_70136622953600'",
  "app/helpers/application_helper.rb:10:in `render_if_exists'",
  "app/views/shared/milestones/_top.html.haml:56:in `_app_views_shared_milestones__top_html_haml___2629497905139223102_70136621428040'",
  "app/views/groups/milestones/show.html.haml:2:in `_app_views_groups_milestones_show_html_haml___2379218561344713234_70136621019980'",
  "app/controllers/application_controller.rb:123:in `render'",
  "ee/lib/gitlab/ip_address_state.rb:10:in `with'",
  "ee/app/controllers/ee/application_controller.rb:46:in `set_current_ip_address'",
  "lib/gitlab/session.rb:11:in `with_session'",
  "app/controllers/application_controller.rb:461:in `set_session_storage'",
  "app/controllers/application_controller.rb:455:in `set_locale'",
  "ee/lib/omni_auth/strategies/group_saml.rb:39:in `other_phase'",
  "ee/lib/gitlab/jira/middleware.rb:19:in `call'"
]

This suggests that we're being inefficient in how we check if issue weights are available.

  1. Licenses are only available on the entire instance (for self-managed) or the top-level group (for GitLab.com).
  2. We therefore only need a single license check for weight per page load.
  3. It looks like we're doing (at least) one license check per issue in the burndown chart.