[go: up one dir, main page]

Skip to content

Investigate N+1 queries on MR approval rules REST API endpoint

When making a request like GET api/v4/projects/:id/merge_requests/:iid/approval_rules there are a number of different n+1 queries. For example queries like:

SELECT "namespaces"."id", "namespaces"."name", "namespaces"."path", "namespaces"."owner_id", "namespaces"."created_at", "namespaces"."updated_at", "namespaces"."type", "namespaces"."avatar", "namespaces"."membership_lock", "namespaces"."share_with_group_lock", "namespaces"."visibility_level", "namespaces"."request_access_enabled", "namespaces"."ldap_sync_status", "namespaces"."ldap_sync_error", "namespaces"."ldap_sync_last_update_at", "namespaces"."ldap_sync_last_successful_update_at", "namespaces"."ldap_sync_last_sync_at", "namespaces"."lfs_enabled", "namespaces"."parent_id", "namespaces"."shared_runners_minutes_limit", "namespaces"."repository_size_limit", "namespaces"."require_two_factor_authentication", "namespaces"."two_factor_grace_period", "namespaces"."project_creation_level", "namespaces"."runners_token", "namespaces"."file_template_project_id", "namespaces"."saml_discovery_token", "namespaces"."runners_token_encrypted", "namespaces"."custom_project_templates_group_id", "namespaces"."auto_devops_enabled", "namespaces"."extra_shared_runners_minutes_limit", "namespaces"."last_ci_minutes_notification_at", "namespaces"."last_ci_minutes_usage_notification_level", "namespaces"."subgroup_creation_level", "namespaces"."max_pages_size", "namespaces"."max_artifacts_size", "namespaces"."mentions_disabled", "namespaces"."default_branch_protection", "namespaces"."max_personal_access_token_lifetime", "namespaces"."push_rule_id", "namespaces"."shared_runners_enabled", "namespaces"."allow_descendants_override_disabled_shared_runners", "namespaces"."traversal_ids", "namespaces"."organization_id" FROM "namespaces" INNER JOIN "approval_merge_request_rules_groups" ON "namespaces"."id" = "approval_merge_request_rules_groups"."group_id" WHERE "namespaces"."type" = 'Group' AND "approval_merge_request_rules_groups"."approval_merge_request_rule_id" = 262549831 

from serializing the group attribute:

[
  "lib/peek/views/active_record.rb:55:in `block in setup_subscribers'",
  "app/models/concerns/use_sql_function_for_primary_key_lookups.rb:10:in `_query_by_sql'",
  "ee/app/models/ee/preloaders/group_policy_preloader.rb:10:in `execute'",
  "app/models/group.rb:333:in `block in <class:Group>'",
  "ee/app/finders/approval_rules/group_finder.rb:17:in `block in visible_groups'",
  "ee/app/finders/approval_rules/group_finder.rb:16:in `visible_groups'",
  "ee/app/presenters/approval_rule_presenter.rb:22:in `groups'",
  "lib/gitlab/json.rb:130:in `dump'",
  "lib/gitlab/json.rb:130:in `adapter_dump'",
  "lib/gitlab/json.rb:52:in `dump'",
  "lib/gitlab/json.rb:191:in `call'",
  "lib/gitlab/ip_address_state.rb:11:in `with'",
  "lib/api/api_guard.rb:266:in `call'",
  "ee/lib/omni_auth/strategies/group_saml.rb:41:in `other_phase'",
  "lib/gitlab/sidekiq_sharding/validator.rb:42:in `enabled'",
  "lib/gitlab/database/query_analyzer.rb:83:in `within'",
  "lib/ci/job_token/middleware.rb:11:in `call'"
]

There are a bunch of other examples. It doesn't seem like associations are eager loaded: https://gitlab.com/gitlab-org/gitlab/-/blob/dce82e2b237d05ef5e650de3e40fa7c07caa3ca5/ee/lib/api/merge_request_approval_rules.rb#L31-33

Edited by 🤖 GitLab Bot 🤖