feat(server): improve checkAlbumAccess query performance (#22467)

* Fix slow SQL query in checkAlbumAccess caused by the array overlap operator &&

* Update access.repository.sql

* Rewrite the query to pass assetIds once as a single array parameter
This commit is contained in:
Sergey Katsubo 2025-10-06 18:54:07 +03:00 committed by GitHub
parent 1a2a46014e
commit 9da138e01e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 17 additions and 5 deletions

View File

@ -71,6 +71,11 @@ where
and "shared_link"."albumId" in ($2)
-- AccessRepository.asset.checkAlbumAccess
with
"target" as (
select
array[$1]::uuid[] as "ids"
)
select
"asset"."id",
"asset"."livePhotoVideoId"
@ -82,8 +87,12 @@ from
left join "album_user" as "albumUsers" on "albumUsers"."albumsId" = "album"."id"
left join "user" on "user"."id" = "albumUsers"."usersId"
and "user"."deletedAt" is null
cross join "target"
where
array["asset"."id", "asset"."livePhotoVideoId"] && array[$1]::uuid[]
(
"asset"."id" = any (target.ids)
or "asset"."livePhotoVideoId" = any (target.ids)
)
and (
"album"."ownerId" = $2
or "user"."id" = $3

View File

@ -136,6 +136,7 @@ class AssetAccess {
}
return this.db
.with('target', (qb) => qb.selectNoFrom(sql`array[${sql.join([...assetIds])}]::uuid[]`.as('ids')))
.selectFrom('album')
.innerJoin('album_asset as albumAssets', 'album.id', 'albumAssets.albumsId')
.innerJoin('asset', (join) =>
@ -143,11 +144,13 @@ class AssetAccess {
)
.leftJoin('album_user as albumUsers', 'albumUsers.albumsId', 'album.id')
.leftJoin('user', (join) => join.onRef('user.id', '=', 'albumUsers.usersId').on('user.deletedAt', 'is', null))
.crossJoin('target')
.select(['asset.id', 'asset.livePhotoVideoId'])
.where(
sql`array["asset"."id", "asset"."livePhotoVideoId"]`,
'&&',
sql`array[${sql.join([...assetIds])}]::uuid[] `,
.where((eb) =>
eb.or([
eb('asset.id', '=', sql<string>`any(target.ids)`),
eb('asset.livePhotoVideoId', '=', sql<string>`any(target.ids)`),
]),
)
.where((eb) => eb.or([eb('album.ownerId', '=', userId), eb('user.id', '=', userId)]))
.where('album.deletedAt', 'is', null)