From 4fe38c62ddc2a3a85c4674584e31e37bff4d2139 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julius=20H=C3=A4rtl?= Date: Thu, 13 Jul 2023 16:19:07 +0200 Subject: [PATCH] fix: Split query to fetch board ids to avoid slow query join MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Julius Härtl --- lib/Db/BoardMapper.php | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/lib/Db/BoardMapper.php b/lib/Db/BoardMapper.php index dfc742bb5..8f44c003b 100644 --- a/lib/Db/BoardMapper.php +++ b/lib/Db/BoardMapper.php @@ -106,44 +106,54 @@ public function find($id, $withLabels = false, $withAcl = false): Board { } public function findBoardIds(string $userId): array { + // Owned by the user $qb = $this->db->getQueryBuilder(); $qb->selectDistinct('b.id') ->from($this->getTableName(), 'b') - ->leftJoin('b', 'deck_board_acl', 'acl', $qb->expr()->eq('b.id', 'acl.board_id')); + ->where($qb->expr()->andX( + $qb->expr()->eq('owner', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)), + )); + $result = $qb->executeQuery(); + $ownerBoards = array_map(function (string $id) { + return (int)$id; + }, $result->fetchAll(\PDO::FETCH_COLUMN)); + $result->closeCursor(); - // Owned by the user - $qb->where($qb->expr()->andX( - $qb->expr()->eq('owner', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)), - )); + $qb = $this->db->getQueryBuilder(); + $qb->selectDistinct('b.id') + ->from($this->getTableName(), 'b') + ->innerJoin('b', 'deck_board_acl', 'acl', $qb->expr()->eq('b.id', 'acl.board_id')); // Shared to the user - $qb->orWhere($qb->expr()->andX( - $qb->expr()->eq('acl.participant', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)), + $qb->where($qb->expr()->andX( $qb->expr()->eq('acl.type', $qb->createNamedParameter(Acl::PERMISSION_TYPE_USER, IQueryBuilder::PARAM_INT)), + $qb->expr()->eq('acl.participant', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)), )); // Shared to user groups of the user $groupIds = $this->groupManager->getUserGroupIds($this->userManager->get($userId)); if (count($groupIds) !== 0) { $qb->orWhere($qb->expr()->andX( - $qb->expr()->in('acl.participant', $qb->createNamedParameter($groupIds, IQueryBuilder::PARAM_STR_ARRAY)), - $qb->expr()->eq('acl.type', $qb->createNamedParameter(Acl::PERMISSION_TYPE_GROUP, IQueryBuilder::PARAM_INT)), - )); + $qb->expr()->eq('acl.type', $qb->createNamedParameter(Acl::PERMISSION_TYPE_GROUP, IQueryBuilder::PARAM_INT)), + $qb->expr()->in('acl.participant', $qb->createNamedParameter($groupIds, IQueryBuilder::PARAM_STR_ARRAY)), + )); } // Shared to circles of the user $circles = $this->circlesService->getUserCircles($userId); if (count($circles) !== 0) { $qb->orWhere($qb->expr()->andX( - $qb->expr()->in('acl.participant', $qb->createNamedParameter($circles, IQueryBuilder::PARAM_STR_ARRAY)), $qb->expr()->eq('acl.type', $qb->createNamedParameter(Acl::PERMISSION_TYPE_CIRCLE, IQueryBuilder::PARAM_INT)), + $qb->expr()->in('acl.participant', $qb->createNamedParameter($circles, IQueryBuilder::PARAM_STR_ARRAY)), )); } $result = $qb->executeQuery(); - return array_map(function (string $id) { + $sharedBoards = array_map(function (string $id) { return (int)$id; }, $result->fetchAll(\PDO::FETCH_COLUMN)); + $result->closeCursor(); + return array_unique(array_merge($ownerBoards, $sharedBoards)); } public function findAllForUser(string $userId, ?int $since = null, bool $includeArchived = true, ?int $before = null,