perf(server): only serialize exif for returned search rows (#32620)

(cherry picked from commit e51de38c40a29fd5eb1347cd991bbbafccfe62c6)
This commit is contained in:
bo0tzz
2026-10-28 20:41:41 +03:00
committed by Codex
parent dc5553b239
commit 8e3e3a48ae
3 changed files with 217 additions and 7 deletions
+126 -3
View File
@@ -38,7 +38,48 @@ select
and "asset_file"."type" = $1
) as agg
) as "files",
to_json("asset_exif") as "exifInfo"
(
select
to_json(obj)
from
(
select
"asset_exif"."assetId",
"asset_exif"."autoStackId",
"asset_exif"."bitsPerSample",
"asset_exif"."city",
"asset_exif"."colorspace",
"asset_exif"."country",
"asset_exif"."dateTimeOriginal",
"asset_exif"."description",
"asset_exif"."exifImageHeight",
"asset_exif"."exifImageWidth",
"asset_exif"."exposureTime",
"asset_exif"."fileSizeInByte",
"asset_exif"."fNumber",
"asset_exif"."focalLength",
"asset_exif"."fps",
"asset_exif"."iso",
"asset_exif"."latitude",
"asset_exif"."lensModel",
"asset_exif"."livePhotoCID",
"asset_exif"."longitude",
"asset_exif"."make",
"asset_exif"."model",
"asset_exif"."modifyDate",
"asset_exif"."orientation",
"asset_exif"."profileDescription",
"asset_exif"."projectionType",
"asset_exif"."rating",
"asset_exif"."state",
"asset_exif"."tags",
"asset_exif"."timeZone"
from
"asset_exif"
where
"asset_exif"."assetId" = "asset"."id"
) as obj
) as "exifInfo"
from
"asset"
inner join "asset_exif" on "asset"."id" = "asset_exif"."assetId"
@@ -239,7 +280,48 @@ select
"asset_edit"."assetId" = "asset"."id"
) as agg
) as "edits",
to_json("asset_exif") as "exifInfo",
(
select
to_json(obj)
from
(
select
"asset_exif"."assetId",
"asset_exif"."autoStackId",
"asset_exif"."bitsPerSample",
"asset_exif"."city",
"asset_exif"."colorspace",
"asset_exif"."country",
"asset_exif"."dateTimeOriginal",
"asset_exif"."description",
"asset_exif"."exifImageHeight",
"asset_exif"."exifImageWidth",
"asset_exif"."exposureTime",
"asset_exif"."fileSizeInByte",
"asset_exif"."fNumber",
"asset_exif"."focalLength",
"asset_exif"."fps",
"asset_exif"."iso",
"asset_exif"."latitude",
"asset_exif"."lensModel",
"asset_exif"."livePhotoCID",
"asset_exif"."longitude",
"asset_exif"."make",
"asset_exif"."model",
"asset_exif"."modifyDate",
"asset_exif"."orientation",
"asset_exif"."profileDescription",
"asset_exif"."projectionType",
"asset_exif"."rating",
"asset_exif"."state",
"asset_exif"."tags",
"asset_exif"."timeZone"
from
"asset_exif"
where
"asset_exif"."assetId" = "asset"."id"
) as obj
) as "exifInfo",
(
select
to_json(obj)
@@ -449,7 +531,48 @@ where
select
"asset"."id",
"asset"."visibility",
to_json("asset_exif") as "exifInfo",
(
select
to_json(obj)
from
(
select
"asset_exif"."assetId",
"asset_exif"."autoStackId",
"asset_exif"."bitsPerSample",
"asset_exif"."city",
"asset_exif"."colorspace",
"asset_exif"."country",
"asset_exif"."dateTimeOriginal",
"asset_exif"."description",
"asset_exif"."exifImageHeight",
"asset_exif"."exifImageWidth",
"asset_exif"."exposureTime",
"asset_exif"."fileSizeInByte",
"asset_exif"."fNumber",
"asset_exif"."focalLength",
"asset_exif"."fps",
"asset_exif"."iso",
"asset_exif"."latitude",
"asset_exif"."lensModel",
"asset_exif"."livePhotoCID",
"asset_exif"."longitude",
"asset_exif"."make",
"asset_exif"."model",
"asset_exif"."modifyDate",
"asset_exif"."orientation",
"asset_exif"."profileDescription",
"asset_exif"."projectionType",
"asset_exif"."rating",
"asset_exif"."state",
"asset_exif"."tags",
"asset_exif"."timeZone"
from
"asset_exif"
where
"asset_exif"."assetId" = "asset"."id"
) as obj
) as "exifInfo",
(
select
coalesce(json_agg(agg), '[]')
+84 -2
View File
@@ -134,7 +134,48 @@ select
"asset"."type",
"asset"."width",
"asset"."height",
to_json("asset_exif") as "exifInfo"
(
select
to_json(obj)
from
(
select
"asset_exif"."assetId",
"asset_exif"."autoStackId",
"asset_exif"."bitsPerSample",
"asset_exif"."city",
"asset_exif"."colorspace",
"asset_exif"."country",
"asset_exif"."dateTimeOriginal",
"asset_exif"."description",
"asset_exif"."exifImageHeight",
"asset_exif"."exifImageWidth",
"asset_exif"."exposureTime",
"asset_exif"."fileSizeInByte",
"asset_exif"."fNumber",
"asset_exif"."focalLength",
"asset_exif"."fps",
"asset_exif"."iso",
"asset_exif"."latitude",
"asset_exif"."lensModel",
"asset_exif"."livePhotoCID",
"asset_exif"."longitude",
"asset_exif"."make",
"asset_exif"."model",
"asset_exif"."modifyDate",
"asset_exif"."orientation",
"asset_exif"."profileDescription",
"asset_exif"."projectionType",
"asset_exif"."rating",
"asset_exif"."state",
"asset_exif"."tags",
"asset_exif"."timeZone"
from
"asset_exif"
where
"asset_exif"."assetId" = "asset"."id"
) as obj
) as "exifInfo"
from
"asset"
inner join "asset_exif" on "asset"."id" = "asset_exif"."assetId"
@@ -1420,7 +1461,48 @@ offset
-- SearchRepository.searchMetadataV3 (order-rating-withExif)
select
to_json("asset_exif") as "exifInfo",
(
select
to_json(obj)
from
(
select
"asset_exif"."assetId",
"asset_exif"."autoStackId",
"asset_exif"."bitsPerSample",
"asset_exif"."city",
"asset_exif"."colorspace",
"asset_exif"."country",
"asset_exif"."dateTimeOriginal",
"asset_exif"."description",
"asset_exif"."exifImageHeight",
"asset_exif"."exifImageWidth",
"asset_exif"."exposureTime",
"asset_exif"."fileSizeInByte",
"asset_exif"."fNumber",
"asset_exif"."focalLength",
"asset_exif"."fps",
"asset_exif"."iso",
"asset_exif"."latitude",
"asset_exif"."lensModel",
"asset_exif"."livePhotoCID",
"asset_exif"."longitude",
"asset_exif"."make",
"asset_exif"."model",
"asset_exif"."modifyDate",
"asset_exif"."orientation",
"asset_exif"."profileDescription",
"asset_exif"."projectionType",
"asset_exif"."rating",
"asset_exif"."state",
"asset_exif"."tags",
"asset_exif"."timeZone"
from
"asset_exif"
where
"asset_exif"."assetId" = "asset"."id"
) as obj
) as "exifInfo",
"asset"."id",
"asset"."updateId",
"asset"."createdAt",
+7 -2
View File
@@ -123,10 +123,15 @@ export function withExif<O>(qb: SelectQueryBuilder<DB, 'asset', O>) {
return qb.leftJoin('asset_exif', 'asset.id', 'asset_exif.assetId').select(selectExifInfo);
}
const selectReturnedExifInfo = (eb: ExpressionBuilder<DB, 'asset'>) =>
jsonObjectFrom(eb.selectFrom('asset_exif').select(columns.exif).whereRef('asset_exif.assetId', '=', 'asset.id')).as(
'exifInfo',
);
export function withExifInner<O>(qb: SelectQueryBuilder<DB, 'asset', O>) {
return qb
.innerJoin('asset_exif', 'asset.id', 'asset_exif.assetId')
.select((eb) => eb.fn.toJson(eb.table('asset_exif')).as('exifInfo'))
.select(selectReturnedExifInfo)
.$narrowType<{ exifInfo: NotNull }>();
}
@@ -816,7 +821,7 @@ export function searchAssetBuilder(kysely: Kysely<DB>, options: AssetSearchBuild
.selectFrom('asset')
// postgres eliminates the left join when no exif column is referenced, so unused joins are free
.leftJoin('asset_exif', 'asset.id', 'asset_exif.assetId')
.$if(!!options.withExif, (qb) => qb.select(selectExifInfo))
.$if(!!options.withExif, (qb) => qb.select(selectReturnedExifInfo))
.$if(scopeGlobally, (qb) => qb.where(ownershipPredicate))
.where((eb) =>
eb.or([eb('asset.visibility', '!=', AssetVisibility.Locked), eb('asset.ownerId', '=', scope.lockedOwnerId)]),