perf: add indexes to improve People API response times (#26337)

Add SQL indexes for people search endpoints
This commit is contained in:
David Baxter 2026-02-19 13:09:05 -08:00 committed by GitHub
parent e6ac48f4b5
commit 5c7c07a09f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 25 additions and 0 deletions

View File

@ -0,0 +1,15 @@
import { Kysely, sql } from 'kysely';
export async function up(db: Kysely<any>): Promise<void> {
await sql`CREATE INDEX "asset_id_timeline_notDeleted_idx" ON "asset" ("id") WHERE visibility = 'timeline' AND "deletedAt" IS NULL;`.execute(db);
await sql`CREATE INDEX "asset_face_personId_assetId_notDeleted_isVisible_idx" ON "asset_face" ("personId", "assetId") WHERE "deletedAt" IS NULL AND "isVisible" IS TRUE;`.execute(db);
await sql`INSERT INTO "migration_overrides" ("name", "value") VALUES ('index_asset_id_timeline_notDeleted_idx', '{"type":"index","name":"asset_id_timeline_notDeleted_idx","sql":"CREATE INDEX \\"asset_id_timeline_notDeleted_idx\\" ON \\"asset\\" (\\"id\\") WHERE visibility = ''timeline'' AND \\"deletedAt\\" IS NULL;"}'::jsonb);`.execute(db);
await sql`INSERT INTO "migration_overrides" ("name", "value") VALUES ('index_asset_face_personId_assetId_notDeleted_isVisible_idx', '{"type":"index","name":"asset_face_personId_assetId_notDeleted_isVisible_idx","sql":"CREATE INDEX \\"asset_face_personId_assetId_notDeleted_isVisible_idx\\" ON \\"asset_face\\" (\\"personId\\", \\"assetId\\") WHERE \\"deletedAt\\" IS NULL AND \\"isVisible\\" IS TRUE;"}'::jsonb);`.execute(db);
}
export async function down(db: Kysely<any>): Promise<void> {
await sql`DROP INDEX "asset_id_timeline_notDeleted_idx";`.execute(db);
await sql`DROP INDEX "asset_face_personId_assetId_notDeleted_isVisible_idx";`.execute(db);
await sql`DELETE FROM "migration_overrides" WHERE "name" = 'index_asset_id_timeline_notDeleted_idx';`.execute(db);
await sql`DELETE FROM "migration_overrides" WHERE "name" = 'index_asset_face_personId_assetId_notDeleted_isVisible_idx';`.execute(db);
}

View File

@ -27,6 +27,11 @@ import {
})
// schemaFromDatabase does not preserve column order
@Index({ name: 'asset_face_assetId_personId_idx', columns: ['assetId', 'personId'] })
@Index({
name: 'asset_face_personId_assetId_notDeleted_isVisible_idx',
columns: ['personId', 'assetId'],
where: '"deletedAt" IS NULL AND "isVisible" IS TRUE',
})
@Index({ columns: ['personId', 'assetId'] })
export class AssetFaceTable {
@PrimaryGeneratedColumn()

View File

@ -55,6 +55,11 @@ import { ASSET_CHECKSUM_CONSTRAINT } from 'src/utils/database';
using: 'gin',
expression: 'f_unaccent("originalFileName") gin_trgm_ops',
})
@Index({
name: 'asset_id_timeline_notDeleted_idx',
columns: ['id'],
where: `visibility = 'timeline' AND "deletedAt" IS NULL`,
})
// For all assets, each originalpath must be unique per user and library
export class AssetTable {
@PrimaryGeneratedColumn()