Commit e4efeb7e authored by Furkan Ayhan's avatar Furkan Ayhan Committed by Adam Hegyi

Optimize User#ci_owned_runners query V3

This will move two subqueries into CTEs
and let them use the existing index with smarter query plans.

Changelog: performance
parent 83573907
...@@ -11,8 +11,6 @@ module Ci ...@@ -11,8 +11,6 @@ module Ci
end end
scope :contains_any_of_namespaces, -> (ids) do scope :contains_any_of_namespaces, -> (ids) do
return none if ids.empty?
where('traversal_ids && ARRAY[?]::int[]', ids) where('traversal_ids && ARRAY[?]::int[]', ids)
end end
......
...@@ -2220,27 +2220,43 @@ class User < ApplicationRecord ...@@ -2220,27 +2220,43 @@ class User < ApplicationRecord
end end
def ci_owned_project_runners_from_project_members def ci_owned_project_runners_from_project_members
Ci::RunnerProject project_ids = project_members.where('access_level >= ?', Gitlab::Access::MAINTAINER).pluck(:source_id)
.select('ci_runners.*')
.joins(:runner) Ci::Runner
.where(project: project_members.where('access_level >= ?', Gitlab::Access::MAINTAINER).pluck(:source_id)) .joins(:runner_projects)
.where(runner_projects: { project: project_ids })
end end
def ci_owned_project_runners_from_group_members def ci_owned_project_runners_from_group_members
Ci::RunnerProject cte_namespace_ids = Gitlab::SQL::CTE.new(
.select('ci_runners.*') :cte_namespace_ids,
.joins(:runner) ci_namespace_mirrors_for_group_members(Gitlab::Access::MAINTAINER).select(:namespace_id)
.joins('JOIN ci_project_mirrors ON ci_project_mirrors.project_id = ci_runner_projects.project_id') )
.joins('JOIN ci_namespace_mirrors ON ci_namespace_mirrors.namespace_id = ci_project_mirrors.namespace_id')
.merge(ci_namespace_mirrors_for_group_members(Gitlab::Access::MAINTAINER)) cte_project_ids = Gitlab::SQL::CTE.new(
:cte_project_ids,
Ci::ProjectMirror
.select(:project_id)
.where('ci_project_mirrors.namespace_id IN (SELECT namespace_id FROM cte_namespace_ids)')
)
Ci::Runner
.with(cte_namespace_ids.to_arel)
.with(cte_project_ids.to_arel)
.joins(:runner_projects)
.where('ci_runner_projects.project_id IN (SELECT project_id FROM cte_project_ids)')
end end
def ci_owned_group_runners def ci_owned_group_runners
Ci::RunnerNamespace cte_namespace_ids = Gitlab::SQL::CTE.new(
.select('ci_runners.*') :cte_namespace_ids,
.joins(:runner) ci_namespace_mirrors_for_group_members(Gitlab::Access::OWNER).select(:namespace_id)
.joins('JOIN ci_namespace_mirrors ON ci_namespace_mirrors.namespace_id = ci_runner_namespaces.namespace_id') )
.merge(ci_namespace_mirrors_for_group_members(Gitlab::Access::OWNER))
Ci::Runner
.with(cte_namespace_ids.to_arel)
.joins(:runner_namespaces)
.where('ci_runner_namespaces.namespace_id IN (SELECT namespace_id FROM cte_namespace_ids)')
end end
def ci_namespace_mirrors_for_group_members(level) def ci_namespace_mirrors_for_group_members(level)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment