diff options
author | Mayra Cabrera <mcabrera@gitlab.com> | 2019-07-29 22:33:57 +0000 |
---|---|---|
committer | Mayra Cabrera <mcabrera@gitlab.com> | 2019-07-29 22:33:57 +0000 |
commit | 8b9ad9c6cc922bc518cdf201501330e83960353a (patch) | |
tree | 765fa38cd7b6e6506805cc8a3daac722637d4912 | |
parent | 18e3dcc65e399642918e9a7a90fcafd391a1038d (diff) | |
parent | 66d48385ecaf46b7ddfe0bd33440baaf4ff81a77 (diff) | |
download | gitlab-ce-8b9ad9c6cc922bc518cdf201501330e83960353a.tar.gz |
Merge branch '64180-membersfinder-contains-slow-database-query-with-or-conditions' into 'master'
Resolve "MembersFinder contains slow database query with OR conditions"
Closes #64180
See merge request gitlab-org/gitlab-ce!30451
-rw-r--r-- | app/finders/group_members_finder.rb | 12 | ||||
-rw-r--r-- | app/models/members/group_member.rb | 2 | ||||
-rw-r--r-- | changelogs/unreleased/64180-membersfinder-contains-slow-database-query-with-or-conditions.yml | 5 |
3 files changed, 13 insertions, 6 deletions
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 |