From 66d48385ecaf46b7ddfe0bd33440baaf4ff81a77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=F0=9F=99=88=20=20jacopo=20beschi=20=F0=9F=99=89?= Date: Mon, 29 Jul 2019 22:33:57 +0000 Subject: Resolve "MembersFinder contains slow database query with OR conditions" --- app/finders/group_members_finder.rb | 12 ++++++------ app/models/members/group_member.rb | 2 ++ ...inder-contains-slow-database-query-with-or-conditions.yml | 5 +++++ 3 files changed, 13 insertions(+), 6 deletions(-) create mode 100644 changelogs/unreleased/64180-membersfinder-contains-slow-database-query-with-or-conditions.yml diff --git a/app/finders/group_members_finder.rb b/app/finders/group_members_finder.rb index eebc67cfa9e..33ec6a715f9 100644 --- a/app/finders/group_members_finder.rb +++ b/app/finders/group_members_finder.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class GroupMembersFinder +class GroupMembersFinder < UnionFinder def initialize(group) @group = group end @@ -8,18 +8,18 @@ class GroupMembersFinder # rubocop: disable CodeReuse/ActiveRecord def execute(include_descendants: false) group_members = @group.members - wheres = [] + relations = [] return group_members unless @group.parent || include_descendants - wheres << "members.id IN (#{group_members.select(:id).to_sql})" + relations << group_members if @group.parent parents_members = GroupMember.non_request .where(source_id: @group.ancestors.select(:id)) .where.not(user_id: @group.users.select(:id)) - wheres << "members.id IN (#{parents_members.select(:id).to_sql})" + relations << parents_members end if include_descendants @@ -27,10 +27,10 @@ class GroupMembersFinder .where(source_id: @group.descendants.select(:id)) .where.not(user_id: @group.users.select(:id)) - wheres << "members.id IN (#{descendant_members.select(:id).to_sql})" + relations << descendant_members end - GroupMember.where(wheres.join(' OR ')) + find_union(relations, GroupMember) end # rubocop: enable CodeReuse/ActiveRecord end diff --git a/app/models/members/group_member.rb b/app/models/members/group_member.rb index 4cba69069bb..f6b19317c50 100644 --- a/app/models/members/group_member.rb +++ b/app/models/members/group_member.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true class GroupMember < Member + include FromUnion + SOURCE_TYPE = 'Namespace'.freeze belongs_to :group, foreign_key: 'source_id' diff --git a/changelogs/unreleased/64180-membersfinder-contains-slow-database-query-with-or-conditions.yml b/changelogs/unreleased/64180-membersfinder-contains-slow-database-query-with-or-conditions.yml new file mode 100644 index 00000000000..f86c63a15b6 --- /dev/null +++ b/changelogs/unreleased/64180-membersfinder-contains-slow-database-query-with-or-conditions.yml @@ -0,0 +1,5 @@ +--- +title: Improve MembersFinder query performance using UNION +merge_request: 30451 +author: Jacopo Beschi @jacopo-beschi +type: performance -- cgit v1.2.1