diff --git a/CHANGELOG.md b/CHANGELOG.md index ad4467c4..f3bbad3c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Changed +- Improved repository query performance by adding db indices. [#526](https://github.com/sourcebot-dev/sourcebot/pull/526) + ## [4.7.1] - 2025-09-19 ### Fixed diff --git a/packages/db/prisma/migrations/20250919221836_add_indexes_to_repo_tables/migration.sql b/packages/db/prisma/migrations/20250919221836_add_indexes_to_repo_tables/migration.sql new file mode 100644 index 00000000..2b67f1f9 --- /dev/null +++ b/packages/db/prisma/migrations/20250919221836_add_indexes_to_repo_tables/migration.sql @@ -0,0 +1,5 @@ +-- CreateIndex +CREATE INDEX "Repo_orgId_idx" ON "Repo"("orgId"); + +-- CreateIndex +CREATE INDEX "RepoToConnection_repoId_connectionId_idx" ON "RepoToConnection"("repoId", "connectionId"); diff --git a/packages/db/prisma/schema.prisma b/packages/db/prisma/schema.prisma index 4b75430c..d3304af4 100644 --- a/packages/db/prisma/schema.prisma +++ b/packages/db/prisma/schema.prisma @@ -71,6 +71,7 @@ model Repo { searchContexts SearchContext[] @@unique([external_id, external_codeHostUrl, orgId]) + @@index([orgId]) } model SearchContext { @@ -119,6 +120,7 @@ model RepoToConnection { repoId Int @@id([connectionId, repoId]) + @@index([repoId, connectionId]) } model Invite { diff --git a/packages/db/tools/scriptRunner.ts b/packages/db/tools/scriptRunner.ts index 8e72063a..499a3770 100644 --- a/packages/db/tools/scriptRunner.ts +++ b/packages/db/tools/scriptRunner.ts @@ -4,6 +4,8 @@ import { migrateDuplicateConnections } from "./scripts/migrate-duplicate-connect import { injectAuditData } from "./scripts/inject-audit-data"; import { confirmAction } from "./utils"; import { createLogger } from "@sourcebot/logger"; +import { injectRepoData } from "./scripts/inject-repo-data"; +import { testRepoQueryPerf } from "./scripts/test-repo-query-perf"; export interface Script { run: (prisma: PrismaClient) => Promise; @@ -12,6 +14,8 @@ export interface Script { export const scripts: Record = { "migrate-duplicate-connections": migrateDuplicateConnections, "inject-audit-data": injectAuditData, + "inject-repo-data": injectRepoData, + "test-repo-query-perf": testRepoQueryPerf, } const parser = new ArgumentParser(); diff --git a/packages/db/tools/scripts/inject-repo-data.ts b/packages/db/tools/scripts/inject-repo-data.ts new file mode 100644 index 00000000..209880f3 --- /dev/null +++ b/packages/db/tools/scripts/inject-repo-data.ts @@ -0,0 +1,64 @@ +import { Script } from "../scriptRunner"; +import { PrismaClient } from "../../dist"; +import { createLogger } from "@sourcebot/logger"; + +const logger = createLogger('inject-repo-data'); + +const NUM_REPOS = 100000; + +export const injectRepoData: Script = { + run: async (prisma: PrismaClient) => { + const orgId = 1; + + // Check if org exists + const org = await prisma.org.findUnique({ + where: { id: orgId } + }); + + if (!org) { + await prisma.org.create({ + data: { + id: orgId, + name: 'Test Org', + domain: 'test-org.com' + } + }); + } + + const connection = await prisma.connection.create({ + data: { + orgId, + name: 'test-connection', + connectionType: 'github', + config: {} + } + }); + + + logger.info(`Creating ${NUM_REPOS} repos...`); + + for (let i = 0; i < NUM_REPOS; i++) { + await prisma.repo.create({ + data: { + name: `test-repo-${i}`, + isFork: false, + isArchived: false, + metadata: {}, + cloneUrl: `https://github.com/test-org/test-repo-${i}`, + webUrl: `https://github.com/test-org/test-repo-${i}`, + orgId, + external_id: `test-repo-${i}`, + external_codeHostType: 'github', + external_codeHostUrl: 'https://github.com', + connections: { + create: { + connectionId: connection.id, + } + } + } + }); + } + + logger.info(`Created ${NUM_REPOS} repos.`); + } +}; \ No newline at end of file diff --git a/packages/db/tools/scripts/test-repo-query-perf.ts b/packages/db/tools/scripts/test-repo-query-perf.ts new file mode 100644 index 00000000..ee07d14f --- /dev/null +++ b/packages/db/tools/scripts/test-repo-query-perf.ts @@ -0,0 +1,28 @@ +import { Script } from "../scriptRunner"; +import { PrismaClient } from "../../dist"; +import { createLogger } from "@sourcebot/logger"; + +const logger = createLogger('test-repo-query-perf'); + +export const testRepoQueryPerf: Script = { + run: async (prisma: PrismaClient) => { + + + const start = Date.now(); + const allRepos = await prisma.repo.findMany({ + where: { + orgId: 1, + }, + include: { + connections: { + include: { + connection: true, + } + } + } + }); + + const durationMs = Date.now() - start; + logger.info(`Found ${allRepos.length} repos in ${durationMs}ms`); + } +}; \ No newline at end of file