From c2f8aeeeccaef9598c7ddb10ee29e51c251881ab Mon Sep 17 00:00:00 2001 From: Ian Morland Date: Fri, 6 Mar 2020 14:12:34 +0000 Subject: [PATCH] Improve performance of subqueries (#75) --- extensions/tags/src/Access/DiscussionPolicy.php | 14 ++++++-------- extensions/tags/src/Gambit/TagGambit.php | 16 +++++++--------- .../src/Listener/FilterDiscussionListByTags.php | 7 +++---- 3 files changed, 16 insertions(+), 21 deletions(-) diff --git a/extensions/tags/src/Access/DiscussionPolicy.php b/extensions/tags/src/Access/DiscussionPolicy.php index e131cee6e..2f23ecb01 100755 --- a/extensions/tags/src/Access/DiscussionPolicy.php +++ b/extensions/tags/src/Access/DiscussionPolicy.php @@ -76,11 +76,10 @@ class DiscussionPolicy extends AbstractPolicy public function find(User $actor, Builder $query) { // Hide discussions which have tags that the user is not allowed to see. - $query->whereNotExists(function ($query) use ($actor) { - return $query->selectRaw('1') + $query->whereNotIn('discussions.id', function ($query) use ($actor) { + return $query->select('discussion_id') ->from('discussion_tag') - ->whereIn('tag_id', Tag::getIdsWhereCannot($actor, 'viewDiscussions')) - ->whereColumn('discussions.id', 'discussion_id'); + ->whereIn('tag_id', Tag::getIdsWhereCannot($actor, 'viewDiscussions')); }); // Hide discussions with no tags if the user doesn't have that global @@ -100,11 +99,10 @@ class DiscussionPolicy extends AbstractPolicy // If a discussion requires a certain permission in order for it to be // visible, then we can check if the user has been granted that // permission for any of the discussion's tags. - $query->whereExists(function ($query) use ($actor, $ability) { - return $query->selectRaw('1') + $query->whereIn('discussions.id', function ($query) use ($actor, $ability) { + return $query->select('discussion_id') ->from('discussion_tag') - ->whereIn('tag_id', Tag::getIdsWhereCan($actor, 'discussion.'.$ability)) - ->whereColumn('discussions.id', 'discussion_id'); + ->whereIn('tag_id', Tag::getIdsWhereCan($actor, 'discussion.'.$ability)); }); } diff --git a/extensions/tags/src/Gambit/TagGambit.php b/extensions/tags/src/Gambit/TagGambit.php index a2381a8ff..8dd5a1728 100644 --- a/extensions/tags/src/Gambit/TagGambit.php +++ b/extensions/tags/src/Gambit/TagGambit.php @@ -43,19 +43,17 @@ class TagGambit extends AbstractRegexGambit $search->getQuery()->where(function ($query) use ($slugs, $negate) { foreach ($slugs as $slug) { if ($slug === 'untagged') { - $query->orWhereExists(function ($query) { - $query->selectRaw('1') - ->from('discussion_tag') - ->whereColumn('discussions.id', 'discussion_id'); + $query->orWhereIn('discussions.id', function ($query) { + $query->select('discussion_id') + ->from('discussion_tag'); }, ! $negate); } else { $id = $this->tags->getIdForSlug($slug); - $query->orWhereExists(function ($query) use ($id) { - $query->selectRaw('1') - ->from('discussion_tag') - ->whereColumn('discussions.id', 'discussion_id') - ->where('tag_id', $id); + $query->orWhereIn('discussions.id', function ($query) use ($id) { + $query->select('discussion_id') + ->from('discussion_tag') + ->where('tag_id', $id); }, $negate); } } diff --git a/extensions/tags/src/Listener/FilterDiscussionListByTags.php b/extensions/tags/src/Listener/FilterDiscussionListByTags.php index b7ff59257..9fc8b9bf7 100755 --- a/extensions/tags/src/Listener/FilterDiscussionListByTags.php +++ b/extensions/tags/src/Listener/FilterDiscussionListByTags.php @@ -45,11 +45,10 @@ class FilterDiscussionListByTags return; } - $query->whereNotExists(function ($query) { - return $query->selectRaw('1') + $query->whereNotIn('discussions.id', function ($query) { + return $query->select('discussion_id') ->from('discussion_tag') - ->whereIn('tag_id', Tag::where('is_hidden', 1)->pluck('id')) - ->whereColumn('discussions.id', 'discussion_id'); + ->whereIn('tag_id', Tag::where('is_hidden', 1)->pluck('id')); }); } }