diff --git a/docs/generated/postgres-schema/public.credentials_entity.md b/docs/generated/postgres-schema/public.credentials_entity.md index b7088d0f3ce..89a3629cd6e 100644 --- a/docs/generated/postgres-schema/public.credentials_entity.md +++ b/docs/generated/postgres-schema/public.credentials_entity.md @@ -37,6 +37,7 @@ | Name | Definition | | ---- | ---------- | +| IDX_credentials_entity_is_global | CREATE INDEX "IDX_credentials_entity_is_global" ON public.credentials_entity USING btree (id) WHERE ("isGlobal" = true) | | credentials_entity_pkey | CREATE UNIQUE INDEX credentials_entity_pkey ON public.credentials_entity USING btree (id) | | idx_07fde106c0b471d8cc80a64fc8 | CREATE INDEX idx_07fde106c0b471d8cc80a64fc8 ON public.credentials_entity USING btree (type) | | pk_credentials_entity_id | CREATE UNIQUE INDEX pk_credentials_entity_id ON public.credentials_entity USING btree (id) | diff --git a/docs/generated/sqlite-schema/credentials_entity.md b/docs/generated/sqlite-schema/credentials_entity.md index 67f4accc786..77847c15063 100644 --- a/docs/generated/sqlite-schema/credentials_entity.md +++ b/docs/generated/sqlite-schema/credentials_entity.md @@ -39,6 +39,7 @@ CREATE TABLE "credentials_entity" ("id" varchar(36) PRIMARY KEY NOT NULL, "name" | Name | Definition | | ---- | ---------- | +| IDX_credentials_entity_is_global | CREATE INDEX "IDX_credentials_entity_is_global" ON "credentials_entity" ("id") WHERE "isGlobal" = true | | idx_credentials_entity_type | CREATE INDEX "idx_credentials_entity_type" ON "credentials_entity" ("type") | | sqlite_autoindex_credentials_entity_1 | PRIMARY KEY (id) | diff --git a/packages/@n8n/db/src/migrations/common/1784000000044-AddPartialIndexForGlobalCredentials.ts b/packages/@n8n/db/src/migrations/common/1784000000044-AddPartialIndexForGlobalCredentials.ts new file mode 100644 index 00000000000..a40e1d4851c --- /dev/null +++ b/packages/@n8n/db/src/migrations/common/1784000000044-AddPartialIndexForGlobalCredentials.ts @@ -0,0 +1,28 @@ +import type { MigrationContext, ReversibleMigration } from '../migration-types'; + +/** + * Add a partial index on `credentials_entity` for rows where `isGlobal = true`. + * + * Before every workflow execution, the permission check fetches the IDs of all + * global credentials (`WHERE "isGlobal" = true`). Without an index on this + * flag, that lookup scans the entire credentials table on every run, even + * though only a handful of credentials are global. The partial index contains + * only those rows, so the lookup becomes an index-only scan. + */ +export class AddPartialIndexForGlobalCredentials1784000000044 implements ReversibleMigration { + async up({ schemaBuilder: { createIndex }, tablePrefix }: MigrationContext) { + await createIndex( + 'credentials_entity', + ['id'], + false, + `IDX_${tablePrefix}credentials_entity_is_global`, + '"isGlobal" = true', + ); + } + + async down({ schemaBuilder: { dropIndex }, tablePrefix }: MigrationContext) { + await dropIndex('credentials_entity', ['id'], { + customIndexName: `IDX_${tablePrefix}credentials_entity_is_global`, + }); + } +} diff --git a/packages/@n8n/db/src/migrations/postgresdb/index.ts b/packages/@n8n/db/src/migrations/postgresdb/index.ts index 35b495a5eb7..7761fbbe405 100644 --- a/packages/@n8n/db/src/migrations/postgresdb/index.ts +++ b/packages/@n8n/db/src/migrations/postgresdb/index.ts @@ -217,6 +217,7 @@ import { DropAgentExecutionFallbackColumns1784000000039 } from '../common/178400 import { CreateWorkflowPublicationTriggerStatusTable1784000000040 } from '../common/1784000000040-CreateWorkflowPublicationTriggerStatusTable'; import { AddUsedPrivateCredentialsToExecutionEntity1784000000041 } from '../common/1784000000041-AddUsedPrivateCredentialsToExecutionEntity'; import { CreateSchedulerTables1784000000042 } from '../common/1784000000042-CreateSchedulerTables'; +import { AddPartialIndexForGlobalCredentials1784000000044 } from '../common/1784000000044-AddPartialIndexForGlobalCredentials'; import type { Migration } from '../migration-types'; export const postgresMigrations: Migration[] = [ @@ -439,4 +440,5 @@ export const postgresMigrations: Migration[] = [ AddUsedPrivateCredentialsToExecutionEntity1784000000041, CreateSchedulerTables1784000000042, CreateWorkflowStatisticsDeltaTable1784000000043, + AddPartialIndexForGlobalCredentials1784000000044, ]; diff --git a/packages/@n8n/db/src/migrations/sqlite/index.ts b/packages/@n8n/db/src/migrations/sqlite/index.ts index f8d3eac6fba..dcab99730f1 100644 --- a/packages/@n8n/db/src/migrations/sqlite/index.ts +++ b/packages/@n8n/db/src/migrations/sqlite/index.ts @@ -209,6 +209,7 @@ import { DropAgentExecutionFallbackColumns1784000000039 } from '../common/178400 import { CreateWorkflowPublicationTriggerStatusTable1784000000040 } from '../common/1784000000040-CreateWorkflowPublicationTriggerStatusTable'; import { AddUsedPrivateCredentialsToExecutionEntity1784000000041 } from '../common/1784000000041-AddUsedPrivateCredentialsToExecutionEntity'; import { CreateSchedulerTables1784000000042 } from '../common/1784000000042-CreateSchedulerTables'; +import { AddPartialIndexForGlobalCredentials1784000000044 } from '../common/1784000000044-AddPartialIndexForGlobalCredentials'; const sqliteMigrations: Migration[] = [ InitialMigration1588102412422, @@ -421,6 +422,7 @@ const sqliteMigrations: Migration[] = [ CreateWorkflowPublicationTriggerStatusTable1784000000040, AddUsedPrivateCredentialsToExecutionEntity1784000000041, CreateSchedulerTables1784000000042, + AddPartialIndexForGlobalCredentials1784000000044, ]; export { sqliteMigrations };