summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMayra Cabrera <mcabrera@gitlab.com>2019-07-29 22:33:57 +0000
committerMayra Cabrera <mcabrera@gitlab.com>2019-07-29 22:33:57 +0000
commit8b9ad9c6cc922bc518cdf201501330e83960353a (patch)
tree765fa38cd7b6e6506805cc8a3daac722637d4912
parent18e3dcc65e399642918e9a7a90fcafd391a1038d (diff)
parent66d48385ecaf46b7ddfe0bd33440baaf4ff81a77 (diff)
downloadgitlab-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.rb12
-rw-r--r--app/models/members/group_member.rb2
-rw-r--r--changelogs/unreleased/64180-membersfinder-contains-slow-database-query-with-or-conditions.yml5
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