Skip to content

Commit 219c2cb

Browse files
feat(segment): add indexes for common query paths
Add indexes to frequently queried and foreign-key columns on the segment entity and create a migration to apply them to existing databases. Avoid duplicate or redundant indexes while covering common WHERE, ORDER BY, JOIN, and foreign-key lookups.
1 parent eae7e28 commit 219c2cb

2 files changed

Lines changed: 39 additions & 0 deletions

File tree

src/email-marketing/entities/segment.entity.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
DeleteDateColumn,
88
OneToMany,
99
VersionColumn,
10+
Index,
1011
} from 'typeorm';
1112
import { ApiProperty } from '@nestjs/swagger';
1213
import { SegmentRule } from './segment-rule.entity';
@@ -24,6 +25,7 @@ export class Segment {
2425
version: number;
2526

2627
@ApiProperty()
28+
@Index('IDX_segments_name')
2729
@Column()
2830
name: string;
2931

@@ -32,6 +34,7 @@ export class Segment {
3234
description?: string;
3335

3436
@ApiProperty()
37+
@Index('IDX_segments_isDynamic_createdAt', ['isDynamic', 'createdAt'])
3538
@Column({ default: true })
3639
isDynamic: boolean;
3740

@@ -53,6 +56,9 @@ export class Segment {
5356
@UpdateDateColumn()
5457
updatedAt: Date;
5558

59+
@Index('IDX_segments_deletedAt', ['deletedAt'], {
60+
where: '"deletedAt" IS NULL',
61+
})
5662
@DeleteDateColumn()
5763
deletedAt?: Date;
5864
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { MigrationInterface, QueryRunner } from 'typeorm';
2+
3+
/**
4+
* Adds indexes to the `segments` table for the common list and lookup paths:
5+
*
6+
* - `name` lookup / search
7+
* - `isDynamic` + `createdAt` for active/dynamic segment listings ordered by newest first
8+
* - `deletedAt IS NULL` for soft-delete filtering while retaining an efficient active-only index
9+
*
10+
* These cover the primary query paths without introducing redundant single-column indexes
11+
* on the already-prefixed composite `isDynamic, createdAt` index.
12+
*/
13+
export class AddSegmentIndexes1806000000000 implements MigrationInterface {
14+
public async up(queryRunner: QueryRunner): Promise<void> {
15+
await queryRunner.query(
16+
'CREATE INDEX IF NOT EXISTS "IDX_segments_name" ON "segments" ("name")',
17+
);
18+
19+
await queryRunner.query(
20+
'CREATE INDEX IF NOT EXISTS "IDX_segments_isDynamic_createdAt" ON "segments" ("isDynamic", "createdAt")',
21+
);
22+
23+
await queryRunner.query(
24+
'CREATE INDEX IF NOT EXISTS "IDX_segments_deletedAt" ON "segments" ("deletedAt") WHERE "deletedAt" IS NULL',
25+
);
26+
}
27+
28+
public async down(queryRunner: QueryRunner): Promise<void> {
29+
await queryRunner.query('DROP INDEX IF EXISTS "IDX_segments_deletedAt"');
30+
await queryRunner.query('DROP INDEX IF EXISTS "IDX_segments_isDynamic_createdAt"');
31+
await queryRunner.query('DROP INDEX IF EXISTS "IDX_segments_name"');
32+
}
33+
}

0 commit comments

Comments
 (0)