diff --git a/apps/backend/prisma/migrations/20250831003652_session_id_event_indices/migration.sql b/apps/backend/prisma/migrations/20250831003652_session_id_event_indices/migration.sql new file mode 100644 index 000000000..9d37391d9 --- /dev/null +++ b/apps/backend/prisma/migrations/20250831003652_session_id_event_indices/migration.sql @@ -0,0 +1,6 @@ +-- It's very common to query by sessionId, userId, projectId, branchId, and eventStartedAt at the same time. +-- We can use a composite index to speed up the query. +-- Sadly we can't add this to the Prisma schema itself because Prisma does not understand composite indexes of JSONB fields. +-- So we have to add it manually. +-- (This is similar to the older idx_event_userid_projectid_branchid_eventstartedat index, but with sessionId added.) +CREATE INDEX idx_event_sessionid_userid_projectid_branchid_eventstartedat ON "Event" ((data->>'projectId'), (data->>'branchId'), (data->>'userId'), (data->>'sessionId'), "eventStartedAt"); diff --git a/apps/backend/src/app/api/latest/auth/sessions/crud.tsx b/apps/backend/src/app/api/latest/auth/sessions/crud.tsx index 94ca99228..e20f8df93 100644 --- a/apps/backend/src/app/api/latest/auth/sessions/crud.tsx +++ b/apps/backend/src/app/api/latest/auth/sessions/crud.tsx @@ -49,6 +49,9 @@ export const sessionsCrudHandlers = createLazyProxy(() => createCrudHandlers(ses ? Prisma.sql`data->>'sessionId' = ANY(${Prisma.sql`ARRAY[${Prisma.join(refreshTokenObjs.map(s => s.id))}]`})` : Prisma.sql`FALSE`} AND "systemEventTypeIds" @> '{"$session-activity"}' + AND data->>'userId' = ${query.user_id} + AND data->>'projectId' = ${auth.tenancy.project.id} + AND COALESCE(data->>'branchId', 'main') = ${auth.tenancy.branchId} GROUP BY data->>'sessionId' ) SELECT e.data->>'sessionId' as "sessionId", diff --git a/apps/backend/src/app/api/latest/users/crud.tsx b/apps/backend/src/app/api/latest/users/crud.tsx index 1a9e94d41..9a26dbb08 100644 --- a/apps/backend/src/app/api/latest/users/crud.tsx +++ b/apps/backend/src/app/api/latest/users/crud.tsx @@ -210,7 +210,10 @@ export const getUsersLastActiveAtMillis = async (projectId: string, branchId: st const events = await prisma.$queryRaw>` SELECT data->>'userId' as "userId", MAX("eventStartedAt") as "lastActiveAt" FROM ${sqlQuoteIdent(schema)}."Event" - WHERE data->>'userId' = ANY(${Prisma.sql`ARRAY[${Prisma.join(userIds)}]`}) AND data->>'projectId' = ${projectId} AND COALESCE("data"->>'branchId', 'main') = ${branchId} AND "systemEventTypeIds" @> '{"$user-activity"}' + WHERE data->>'userId' = ANY(${Prisma.sql`ARRAY[${Prisma.join(userIds)}]`}) + AND data->>'projectId' = ${projectId} + AND COALESCE("data"->>'branchId', 'main') = ${branchId} + AND "systemEventTypeIds" @> '{"$user-activity"}' GROUP BY data->>'userId' `;