Skip to content

Commit c8165d2

Browse files
committed
perf(BookmarkMapper): Improve countDuplicated performance
Assisted-by: ClaudeCode:claude-opus-4-8 Signed-off-by: Marcel Klehr <mklehr@gmx.net>
1 parent 9310ddf commit c8165d2

1 file changed

Lines changed: 8 additions & 14 deletions

File tree

lib/Db/BookmarkMapper.php

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -710,25 +710,19 @@ public function countUnavailable(string $userId): int {
710710
* @throws Exception
711711
*/
712712
public function countDuplicated(string $userId): int {
713-
// Count duplicates the exact same way the "Duplicated" list is computed in findAll():
714-
// against the recursive folder_tree CTE (which covers nested folders and bookmarks inside
715-
// shared folders/subfolders) and using the same _filterDuplicated() predicate. Hand-rolled
716-
// queries against the raw bookmarks_tree table miss everything that only becomes visible
717-
// through the recursive expansion, which made this method under-count.
718713
$rootFolder = $this->folderMapper->findRootFolder($userId);
719714
[$cte, $params, $paramTypes] = $this->generateCTE($rootFolder->getId(), false);
720715

721716
$qb = $this->db->getQueryBuilder();
722717
$qb->automaticTablePrefix(false);
723-
$qb->select($qb->createFunction('COUNT(DISTINCT b.id)'))
724-
->from('*PREFIX*bookmarks', 'b')
725-
->innerJoin('b', 'folder_tree', 'tree', 'tree.item_id = b.id AND tree.type = ' . $qb->createPositionalParameter(TreeMapper::TYPE_BOOKMARK) . ' AND tree.soft_deleted_at is NULL');
726-
727-
$queryParams = new QueryParameters();
728-
$queryParams->setDuplicated(true);
729-
$this->_filterDuplicated($qb, $queryParams);
730-
731-
$finalQuery = $cte . ' ' . $qb->getSQL();
718+
$qb->select('tree.item_id')
719+
->from('folder_tree', 'tree')
720+
->where($qb->expr()->eq('tree.type', $qb->createPositionalParameter(TreeMapper::TYPE_BOOKMARK)))
721+
->groupBy('tree.item_id')
722+
->having('COUNT(DISTINCT tree.parent_folder) > 1')
723+
->andHaving('SUM(CASE WHEN tree.soft_deleted_at IS NULL THEN 1 ELSE 0 END) > 0');
724+
725+
$finalQuery = $cte . ' SELECT COUNT(*) FROM (' . $qb->getSQL() . ') dup';
732726
$params = array_merge($params, $qb->getParameters());
733727
$paramTypes = array_merge($paramTypes, $qb->getParameterTypes());
734728

0 commit comments

Comments
 (0)