Commit 40b0f540 authored by Alexis Reigel's avatar Alexis Reigel Committed by Alexis Reigel

use union instead of multiple joins

the unions performs much better than the joins, and the execution time
is constant with a growing number of records.
parent 295184f6
...@@ -29,33 +29,34 @@ module Ci ...@@ -29,33 +29,34 @@ module Ci
scope :ordered, ->() { order(id: :desc) } scope :ordered, ->() { order(id: :desc) }
scope :owned_or_shared, ->(project_id) do scope :owned_or_shared, ->(project_id) do
joins( project_runners = joins(
%{ %{
-- project runners
LEFT JOIN ci_runner_projects ON ci_runner_projects.runner_id = ci_runners.id LEFT JOIN ci_runner_projects ON ci_runner_projects.runner_id = ci_runners.id
}
).where(
%{
ci_runner_projects.project_id = :project_id
},
project_id: project_id
)
-- group runners group_runners = joins(
%{
LEFT JOIN ci_runner_groups ON ci_runner_groups.runner_id = ci_runners.id LEFT JOIN ci_runner_groups ON ci_runner_groups.runner_id = ci_runners.id
LEFT JOIN namespaces ON namespaces.id = ci_runner_groups.group_id LEFT JOIN namespaces ON namespaces.id = ci_runner_groups.group_id
LEFT JOIN projects group_projects ON group_projects.namespace_id = namespaces.id LEFT JOIN projects group_projects ON group_projects.namespace_id = namespaces.id
} }
).where( ).where(
%{ %{
-- project runners
ci_runner_projects.project_id = :project_id
OR
-- group runners
group_projects.id = :project_id group_projects.id = :project_id
OR
-- shared runners
ci_runners.is_shared = true
}, },
project_id: project_id project_id: project_id
) )
shared_runners = where(is_shared: true)
union = Gitlab::SQL::Union.new([project_runners, group_runners, shared_runners])
from("(#{union.to_sql}) ci_runners")
end end
scope :assignable_for, ->(project) do scope :assignable_for, ->(project) do
......
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