Add indices on frequent queries (#12401)

Fixes #12165

Also changed the index naming convention because some were not properly
name and would have caused conflicts in the long run
This commit is contained in:
Félix Malfait
2025-06-02 09:55:45 +02:00
committed by GitHub
parent f6bfec882a
commit 1ef7b7a474
23 changed files with 419 additions and 32 deletions

View File

@ -7,8 +7,8 @@ import {
JoinColumn,
ManyToOne,
PrimaryGeneratedColumn,
UpdateDateColumn,
Unique,
UpdateDateColumn,
} from 'typeorm';
import { Relation } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/relation.interface';
@ -17,7 +17,10 @@ import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
@Entity({ name: 'approvedAccessDomain', schema: 'core' })
@ObjectType()
@Unique('IndexOnDomainAndWorkspaceId', ['domain', 'workspaceId'])
@Unique('IDX_APPROVED_ACCESS_DOMAIN_DOMAIN_WORKSPACE_ID_UNIQUE', [
'domain',
'workspaceId',
])
export class ApprovedAccessDomain {
@PrimaryGeneratedColumn('uuid')
id: string;

View File

@ -20,7 +20,10 @@ import { BillingCustomer } from 'src/engine/core-modules/billing/entities/billin
import { BillingEntitlementKey } from 'src/engine/core-modules/billing/enums/billing-entitlement-key.enum';
@Entity({ name: 'billingEntitlement', schema: 'core' })
@ObjectType()
@Unique('IndexOnFeatureKeyAndWorkspaceIdUnique', ['key', 'workspaceId'])
@Unique('IDX_BILLING_ENTITLEMENT_KEY_WORKSPACE_ID_UNIQUE', [
'key',
'workspaceId',
])
export class BillingEntitlement {
@IDField(() => UUIDScalarType)
@PrimaryGeneratedColumn('uuid')

View File

@ -17,10 +17,10 @@ import { BillingProduct } from 'src/engine/core-modules/billing/entities/billing
import { BillingSubscription } from 'src/engine/core-modules/billing/entities/billing-subscription.entity';
import { BillingSubscriptionItemMetadata } from 'src/engine/core-modules/billing/types/billing-subscription-item-metadata.type';
@Entity({ name: 'billingSubscriptionItem', schema: 'core' })
@Unique('IndexOnBillingSubscriptionIdAndStripeProductIdUnique', [
'billingSubscriptionId',
'stripeProductId',
])
@Unique(
'IDX_BILLING_SUBSCRIPTION_ITEM_BILLING_SUBSCRIPTION_ID_STRIPE_PRODUCT_ID_UNIQUE',
['billingSubscriptionId', 'stripeProductId'],
)
export class BillingSubscriptionItem {
@PrimaryGeneratedColumn('uuid')
id: string;

View File

@ -29,7 +29,7 @@ registerEnumType(SubscriptionStatus, { name: 'SubscriptionStatus' });
registerEnumType(SubscriptionInterval, { name: 'SubscriptionInterval' });
@Entity({ name: 'billingSubscription', schema: 'core' })
@Index('IndexOnActiveSubscriptionPerWorkspace', ['workspaceId'], {
@Index('IDX_BILLING_SUBSCRIPTION_WORKSPACE_ID_UNIQUE', ['workspaceId'], {
unique: true,
where: `status IN ('trialing', 'active', 'past_due')`,
})

View File

@ -18,7 +18,7 @@ import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
@Entity({ name: 'featureFlag', schema: 'core' })
@ObjectType()
@Unique('IndexOnKeyAndWorkspaceIdUnique', ['key', 'workspaceId'])
@Unique('IDX_FEATURE_FLAG_KEY_WORKSPACE_ID_UNIQUE', ['key', 'workspaceId'])
export class FeatureFlag {
@IDField(() => UUIDScalarType)
@PrimaryGeneratedColumn('uuid')

View File

@ -26,15 +26,27 @@ export enum KeyValuePairType {
@Entity({ name: 'keyValuePair', schema: 'core' })
@ObjectType()
@Unique('IndexOnKeyUserIdWorkspaceIdUnique', ['key', 'userId', 'workspaceId'])
@Index('IndexOnKeyWorkspaceIdAndNullUserIdUnique', ['key', 'workspaceId'], {
unique: true,
where: '"userId" is NULL',
})
@Index('IndexOnKeyUserIdAndNullWorkspaceIdUnique', ['key', 'userId'], {
unique: true,
where: '"workspaceId" is NULL',
})
@Unique('IDX_KEY_VALUE_PAIR_KEY_USER_ID_WORKSPACE_ID_UNIQUE', [
'key',
'userId',
'workspaceId',
])
@Index(
'IDX_KEY_VALUE_PAIR_KEY_WORKSPACE_ID_NULL_USER_ID_UNIQUE',
['key', 'workspaceId'],
{
unique: true,
where: '"userId" is NULL',
},
)
@Index(
'IDX_KEY_VALUE_PAIR_KEY_USER_ID_NULL_WORKSPACE_ID_UNIQUE',
['key', 'userId'],
{
unique: true,
where: '"workspaceId" is NULL',
},
)
export class KeyValuePair {
@IDField(() => UUIDScalarType)
@PrimaryGeneratedColumn('uuid')

View File

@ -7,6 +7,7 @@ import {
CreateDateColumn,
DeleteDateColumn,
Entity,
Index,
JoinColumn,
ManyToOne,
OneToMany,
@ -33,7 +34,13 @@ registerEnumType(PermissionsOnAllObjectRecords, {
@Entity({ name: 'userWorkspace', schema: 'core' })
@ObjectType()
@Unique('IndexOnUserIdAndWorkspaceIdUnique', ['userId', 'workspaceId'])
@Unique('IDX_USER_WORKSPACE_USER_ID_WORKSPACE_ID_UNIQUE', [
'userId',
'workspaceId',
])
@Index('IDX_USER_WORKSPACE_ID_DELETED_AT', ['id', 'deletedAt'])
@Index('IDX_USER_WORKSPACE_USER_ID', ['userId'])
@Index('IDX_USER_WORKSPACE_WORKSPACE_ID', ['workspaceId'])
export class UserWorkspace {
@IDField(() => UUIDScalarType)
@PrimaryGeneratedColumn('uuid')

View File

@ -34,6 +34,7 @@ registerEnumType(OnboardingStatus, {
unique: true,
where: '"deletedAt" IS NULL',
})
@Index('IDX_USER_ID_DELETED_AT', ['id', 'deletedAt'])
export class User {
@IDField(() => UUIDScalarType)
@PrimaryGeneratedColumn('uuid')

View File

@ -8,6 +8,7 @@ import {
CreateDateColumn,
DeleteDateColumn,
Entity,
Index,
OneToMany,
PrimaryGeneratedColumn,
Relation,
@ -34,6 +35,7 @@ registerEnumType(WorkspaceActivationStatus, {
)
@Entity({ name: 'workspace', schema: 'core' })
@ObjectType()
@Index('IDX_WORKSPACE_ID_DELETED_AT', ['id', 'deletedAt'])
export class Workspace {
// Fields
@IDField(() => UUIDScalarType)

View File

@ -25,17 +25,21 @@ import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadat
import { RelationMetadataEntity } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity';
@Entity('fieldMetadata')
@Unique('IndexOnNameObjectMetadataIdAndWorkspaceIdUnique', [
@Unique('IDX_FIELD_METADATA_NAME_OBJECT_METADATA_ID_WORKSPACE_ID_UNIQUE', [
'name',
'objectMetadataId',
'workspaceId',
])
@Index('IndexOnRelationTargetFieldMetadataId', [
@Index('IDX_FIELD_METADATA_RELATION_TARGET_FIELD_METADATA_ID', [
'relationTargetFieldMetadataId',
])
@Index('IndexOnRelationTargetObjectMetadataId', [
@Index('IDX_FIELD_METADATA_RELATION_TARGET_OBJECT_METADATA_ID', [
'relationTargetObjectMetadataId',
])
@Index('IDX_FIELD_METADATA_OBJECT_METADATA_ID_WORKSPACE_ID', [
'objectMetadataId',
'workspaceId',
])
export class FieldMetadataEntity<
T extends FieldMetadataType = FieldMetadataType,
> implements FieldMetadataInterface<T>
@ -53,7 +57,7 @@ export class FieldMetadataEntity<
onDelete: 'CASCADE',
})
@JoinColumn({ name: 'objectMetadataId' })
@Index('IndexOnObjectMetadataId')
@Index('IDX_FIELD_METADATA_OBJECT_METADATA_ID', ['objectMetadataId'])
object: Relation<ObjectMetadataEntity>;
@Column({
@ -102,7 +106,7 @@ export class FieldMetadataEntity<
isUnique: boolean;
@Column({ nullable: false, type: 'uuid' })
@Index('IndexOnWorkspaceId')
@Index('IDX_FIELD_METADATA_WORKSPACE_ID', ['workspaceId'])
workspaceId: string;
@Column({ default: false })

View File

@ -32,7 +32,7 @@ export class IndexFieldMetadataEntity {
indexMetadata: Relation<IndexMetadataEntity>;
@Column({ nullable: false })
@Index('IndexOnFieldMetadataId')
@Index('IDX_INDEX_FIELD_METADATA_FIELD_METADATA_ID', ['fieldMetadataId'])
fieldMetadataId: string;
@ManyToOne(

View File

@ -2,6 +2,7 @@ import {
Column,
CreateDateColumn,
Entity,
Index,
JoinColumn,
ManyToOne,
OneToMany,
@ -19,11 +20,15 @@ export enum IndexType {
GIN = 'GIN',
}
@Unique('IndexOnNameAndWorkspaceIdAndObjectMetadataUnique', [
@Unique('IDX_INDEX_METADATA_NAME_WORKSPACE_ID_OBJECT_METADATA_ID_UNIQUE', [
'name',
'workspaceId',
'objectMetadataId',
])
@Index('IDX_INDEX_METADATA_WORKSPACE_ID_OBJECT_METADATA_ID', [
'workspaceId',
'objectMetadataId',
])
@Entity('indexMetadata')
export class IndexMetadataEntity {
@PrimaryGeneratedColumn('uuid')

View File

@ -21,11 +21,14 @@ import { ObjectPermissionEntity } from 'src/engine/metadata-modules/object-permi
import { RelationMetadataEntity } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity';
@Entity('objectMetadata')
@Unique('IndexOnNameSingularAndWorkspaceIdUnique', [
@Unique('IDX_OBJECT_METADATA_NAME_SINGULAR_WORKSPACE_ID_UNIQUE', [
'nameSingular',
'workspaceId',
])
@Unique('IndexOnNamePluralAndWorkspaceIdUnique', ['namePlural', 'workspaceId'])
@Unique('IDX_OBJECT_METADATA_NAME_PLURAL_WORKSPACE_ID_UNIQUE', [
'namePlural',
'workspaceId',
])
export class ObjectMetadataEntity implements ObjectMetadataInterface {
@PrimaryGeneratedColumn('uuid')
id: string;

View File

@ -14,7 +14,10 @@ import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadat
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
@Entity('objectPermission')
@Unique('IndexOnObjectPermissionUnique', ['objectMetadataId', 'roleId'])
@Unique('IDX_OBJECT_PERMISSION_OBJECT_METADATA_ID_ROLE_ID_UNIQUE', [
'objectMetadataId',
'roleId',
])
export class ObjectPermissionEntity {
@PrimaryGeneratedColumn('uuid')
id: string;

View File

@ -14,7 +14,7 @@ import { UserWorkspaceRoleEntity } from 'src/engine/metadata-modules/role/user-w
import { SettingPermissionEntity } from 'src/engine/metadata-modules/setting-permission/setting-permission.entity';
@Entity('role')
@Unique('IndexOnRoleUnique', ['label', 'workspaceId'])
@Unique('IDX_ROLE_LABEL_WORKSPACE_ID_UNIQUE', ['label', 'workspaceId'])
export class RoleEntity {
@PrimaryGeneratedColumn('uuid')
id: string;

View File

@ -2,6 +2,7 @@ import {
Column,
CreateDateColumn,
Entity,
Index,
JoinColumn,
ManyToOne,
PrimaryGeneratedColumn,
@ -13,7 +14,14 @@ import {
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
@Entity('userWorkspaceRole')
@Unique('IndexOnUserWorkspaceRoleUnique', ['userWorkspaceId', 'roleId'])
@Unique('IDX_USER_WORKSPACE_ROLE_USER_WORKSPACE_ID_ROLE_ID_UNIQUE', [
'userWorkspaceId',
'roleId',
])
@Index('IDX_USER_WORKSPACE_ROLE_USER_WORKSPACE_ID_WORKSPACE_ID', [
'userWorkspaceId',
'workspaceId',
])
export class UserWorkspaceRoleEntity {
@PrimaryGeneratedColumn('uuid')
id: string;

View File

@ -14,7 +14,7 @@ import { SettingPermissionType } from 'src/engine/metadata-modules/permissions/c
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
@Entity('settingPermission')
@Unique('IndexOnSettingPermissionUnique', ['setting', 'roleId'])
@Unique('IDX_SETTING_PERMISSION_SETTING_ROLE_ID_UNIQUE', ['setting', 'roleId'])
export class SettingPermissionEntity {
@PrimaryGeneratedColumn('uuid')
id: string;