Skip to content

Commit 2a3a713

Browse files
sameh-faroukclaude
andcommitted
perf: add database indexes to commonly queried entity fields
Add @index directives to schema.graphql for 25 fields across 9 entities, based on analysis of actual query patterns from all downstream consumers: - GraphQL API consumers: tfgrid-sdk-ts (grid_client, playground, dashboard), tfgrid-sdk-go (grid-client, relay-cache-warmer) - Direct DB consumer: grid-proxy reads the processor's PostgreSQL directly via GORM/SQL Indexed fields: - Twin: twinID - Farm: farmID, name, twinID, dedicatedFarm - PublicIp: ip - Node: nodeID, farmID, twinID, certification - NodeContract: contractID, twinID, nodeID, state - NameContract: contractID, twinID, state - RentContract: contractID, twinID, nodeID, state - ContractBillReport: contractID, timestamp - UptimeEvent: nodeID, timestamp No table/column changes — migration contains only CREATE INDEX statements. Grid-proxy's setup.sql indexes (IF NOT EXISTS) coexist without conflict. No processor reindex needed. Fixes: #216 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 288ce73 commit 2a3a713

11 files changed

Lines changed: 117 additions & 33 deletions
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
module.exports = class Data1775123913074 {
2+
name = 'Data1775123913074'
3+
4+
async up(db) {
5+
await db.query(`CREATE INDEX "IDX_a162f043823849732649d40627" ON "twin" ("twin_id") `)
6+
await db.query(`CREATE INDEX "IDX_dc65297fba94a0d984802e7510" ON "public_ip" ("ip") `)
7+
await db.query(`CREATE INDEX "IDX_a09d726d0ff006b47ff4d25428" ON "farm" ("farm_id") `)
8+
await db.query(`CREATE INDEX "IDX_11527b5b142bb3e07f87d45980" ON "farm" ("name") `)
9+
await db.query(`CREATE INDEX "IDX_426e70ba8cefde9d89e36316b0" ON "farm" ("twin_id") `)
10+
await db.query(`CREATE INDEX "IDX_4edaa6f4205d163c8a9ca06cd2" ON "farm" ("dedicated_farm") `)
11+
await db.query(`CREATE INDEX "IDX_e6523793483b172e422dc225ad" ON "node" ("node_id") `)
12+
await db.query(`CREATE INDEX "IDX_3487e44f9bd4d2f06c2af7485b" ON "node" ("farm_id") `)
13+
await db.query(`CREATE INDEX "IDX_a80dbb6074f2ba92c51eb7e8f0" ON "node" ("twin_id") `)
14+
await db.query(`CREATE INDEX "IDX_6802ce0b8ad631c2e6d24d4148" ON "node" ("certification") `)
15+
await db.query(`CREATE INDEX "IDX_8efa24d3a33599e0799f389113" ON "node_contract" ("contract_id") `)
16+
await db.query(`CREATE INDEX "IDX_1f2a420a17a1c0ed5b3d7d4bd2" ON "node_contract" ("twin_id") `)
17+
await db.query(`CREATE INDEX "IDX_e3f1eddc063d323a7f76d58ebd" ON "node_contract" ("node_id") `)
18+
await db.query(`CREATE INDEX "IDX_c4fa9c805975044d13d062f1ba" ON "node_contract" ("state") `)
19+
await db.query(`CREATE INDEX "IDX_7971a8e08495d1ec543ecc24aa" ON "name_contract" ("contract_id") `)
20+
await db.query(`CREATE INDEX "IDX_c7dc9e238cd562ffafa69df542" ON "name_contract" ("twin_id") `)
21+
await db.query(`CREATE INDEX "IDX_3de62d0da1158b282047fd3e06" ON "name_contract" ("state") `)
22+
await db.query(`CREATE INDEX "IDX_fe9c4b4d9beb9dfe1256db4102" ON "rent_contract" ("contract_id") `)
23+
await db.query(`CREATE INDEX "IDX_394aa37f77e27215835510f4ff" ON "rent_contract" ("twin_id") `)
24+
await db.query(`CREATE INDEX "IDX_a5a6f629e36cbad941b5feb0f3" ON "rent_contract" ("node_id") `)
25+
await db.query(`CREATE INDEX "IDX_40167b5192423acdd24d1aa852" ON "rent_contract" ("state") `)
26+
await db.query(`CREATE INDEX "IDX_23c232066e25d61f3a703b1c08" ON "contract_bill_report" ("contract_id") `)
27+
await db.query(`CREATE INDEX "IDX_99e8bdc73230ddcee2c887b0cc" ON "contract_bill_report" ("timestamp") `)
28+
await db.query(`CREATE INDEX "IDX_0cc3aaa9345dd18af9e890998d" ON "uptime_event" ("node_id") `)
29+
await db.query(`CREATE INDEX "IDX_7d8c50572be768ecca6f0ed572" ON "uptime_event" ("timestamp") `)
30+
}
31+
32+
async down(db) {
33+
await db.query(`DROP INDEX "public"."IDX_a162f043823849732649d40627"`)
34+
await db.query(`DROP INDEX "public"."IDX_dc65297fba94a0d984802e7510"`)
35+
await db.query(`DROP INDEX "public"."IDX_a09d726d0ff006b47ff4d25428"`)
36+
await db.query(`DROP INDEX "public"."IDX_11527b5b142bb3e07f87d45980"`)
37+
await db.query(`DROP INDEX "public"."IDX_426e70ba8cefde9d89e36316b0"`)
38+
await db.query(`DROP INDEX "public"."IDX_4edaa6f4205d163c8a9ca06cd2"`)
39+
await db.query(`DROP INDEX "public"."IDX_e6523793483b172e422dc225ad"`)
40+
await db.query(`DROP INDEX "public"."IDX_3487e44f9bd4d2f06c2af7485b"`)
41+
await db.query(`DROP INDEX "public"."IDX_a80dbb6074f2ba92c51eb7e8f0"`)
42+
await db.query(`DROP INDEX "public"."IDX_6802ce0b8ad631c2e6d24d4148"`)
43+
await db.query(`DROP INDEX "public"."IDX_8efa24d3a33599e0799f389113"`)
44+
await db.query(`DROP INDEX "public"."IDX_1f2a420a17a1c0ed5b3d7d4bd2"`)
45+
await db.query(`DROP INDEX "public"."IDX_e3f1eddc063d323a7f76d58ebd"`)
46+
await db.query(`DROP INDEX "public"."IDX_c4fa9c805975044d13d062f1ba"`)
47+
await db.query(`DROP INDEX "public"."IDX_7971a8e08495d1ec543ecc24aa"`)
48+
await db.query(`DROP INDEX "public"."IDX_c7dc9e238cd562ffafa69df542"`)
49+
await db.query(`DROP INDEX "public"."IDX_3de62d0da1158b282047fd3e06"`)
50+
await db.query(`DROP INDEX "public"."IDX_fe9c4b4d9beb9dfe1256db4102"`)
51+
await db.query(`DROP INDEX "public"."IDX_394aa37f77e27215835510f4ff"`)
52+
await db.query(`DROP INDEX "public"."IDX_a5a6f629e36cbad941b5feb0f3"`)
53+
await db.query(`DROP INDEX "public"."IDX_40167b5192423acdd24d1aa852"`)
54+
await db.query(`DROP INDEX "public"."IDX_23c232066e25d61f3a703b1c08"`)
55+
await db.query(`DROP INDEX "public"."IDX_99e8bdc73230ddcee2c887b0cc"`)
56+
await db.query(`DROP INDEX "public"."IDX_0cc3aaa9345dd18af9e890998d"`)
57+
await db.query(`DROP INDEX "public"."IDX_7d8c50572be768ecca6f0ed572"`)
58+
}
59+
}

schema.graphql

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ type Entity @entity {
99

1010
type Twin @entity {
1111
gridVersion: Int!
12-
twinID: Int!
12+
twinID: Int! @index
1313
accountID: String!
1414
relay: String
1515
publicKey: String
@@ -23,28 +23,28 @@ type EntityProof @entity {
2323

2424
type Farm @entity {
2525
gridVersion: Int!
26-
farmID: Int!
27-
name: String!
28-
twinID: Int!
26+
farmID: Int! @index
27+
name: String! @index
28+
twinID: Int! @index
2929
pricingPolicyID: Int!
3030
certification: FarmCertification
3131
publicIPs: [PublicIp!] @derivedFrom(field: "farm")
3232
stellarAddress: String
33-
dedicatedFarm: Boolean
33+
dedicatedFarm: Boolean @index
3434
}
3535

3636
type PublicIp @entity {
3737
farm: Farm!
3838
gateway: String!
39-
ip: String!
39+
ip: String! @index
4040
contractId: BigInt!
4141
}
4242

4343
type Node @entity {
4444
gridVersion: Int!
45-
nodeID: Int!
46-
farmID: Int!
47-
twinID: Int!
45+
nodeID: Int! @index
46+
farmID: Int! @index
47+
twinID: Int! @index
4848
location: Location!
4949
country: String
5050
city: String
@@ -54,7 +54,7 @@ type Node @entity {
5454
created: Int!
5555
farmingPolicyId: Int!
5656
interfaces: [Interfaces!] @derivedFrom(field: "node")
57-
certification: NodeCertification
57+
certification: NodeCertification @index
5858
secure: Boolean
5959
virtualized: Boolean
6060
serialNumber: String
@@ -156,13 +156,13 @@ type City @entity {
156156

157157
type NodeContract @entity {
158158
gridVersion: Int!
159-
contractID: BigInt!
160-
twinID: Int!
161-
nodeID: Int!
159+
contractID: BigInt! @index
160+
twinID: Int! @index
161+
nodeID: Int! @index
162162
deploymentData: String!
163163
deploymentHash: String!
164164
numberOfPublicIPs: Int!
165-
state: ContractState!
165+
state: ContractState! @index
166166
resourcesUsed: ContractResources
167167
createdAt: BigInt!
168168
solutionProviderID: Int
@@ -178,20 +178,20 @@ type ContractResources @entity {
178178

179179
type NameContract @entity {
180180
gridVersion: Int!
181-
contractID: BigInt!
182-
twinID: Int!
181+
contractID: BigInt! @index
182+
twinID: Int! @index
183183
name: String!
184-
state: ContractState!
184+
state: ContractState! @index
185185
createdAt: BigInt!
186186
solutionProviderID: Int
187187
}
188188

189189
type RentContract @entity {
190190
gridVersion: Int!
191-
contractID: BigInt!
192-
twinID: Int!
193-
nodeID: Int!
194-
state: ContractState!
191+
contractID: BigInt! @index
192+
twinID: Int! @index
193+
nodeID: Int! @index
194+
state: ContractState! @index
195195
createdAt: BigInt!
196196
solutionProviderID: Int
197197
}
@@ -224,10 +224,10 @@ type NruConsumption @entity {
224224
}
225225

226226
type ContractBillReport @entity {
227-
contractID: BigInt!
227+
contractID: BigInt! @index
228228
discountReceived: DiscountLevel!
229229
amountBilled: BigInt!
230-
timestamp: BigInt!
230+
timestamp: BigInt! @index
231231
}
232232

233233
enum DiscountLevel {
@@ -256,9 +256,9 @@ type FarmingPolicy @entity {
256256
}
257257

258258
type UptimeEvent @entity {
259-
nodeID: Int!
259+
nodeID: Int! @index
260260
uptime: BigInt!
261-
timestamp: BigInt!
261+
timestamp: BigInt! @index
262262
}
263263

264264
type MintTransaction @entity {

src/model/generated/contractBillReport.model.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {Entity as Entity_, Column as Column_, PrimaryColumn as PrimaryColumn_} from "typeorm"
1+
import {Entity as Entity_, Column as Column_, PrimaryColumn as PrimaryColumn_, Index as Index_} from "typeorm"
22
import * as marshal from "./marshal"
33
import {DiscountLevel} from "./_discountLevel"
44

@@ -11,6 +11,7 @@ export class ContractBillReport {
1111
@PrimaryColumn_()
1212
id!: string
1313

14+
@Index_()
1415
@Column_("numeric", {transformer: marshal.bigintTransformer, nullable: false})
1516
contractID!: bigint
1617

@@ -20,6 +21,7 @@ export class ContractBillReport {
2021
@Column_("numeric", {transformer: marshal.bigintTransformer, nullable: false})
2122
amountBilled!: bigint
2223

24+
@Index_()
2325
@Column_("numeric", {transformer: marshal.bigintTransformer, nullable: false})
2426
timestamp!: bigint
2527
}

src/model/generated/farm.model.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {Entity as Entity_, Column as Column_, PrimaryColumn as PrimaryColumn_, OneToMany as OneToMany_} from "typeorm"
1+
import {Entity as Entity_, Column as Column_, PrimaryColumn as PrimaryColumn_, Index as Index_, OneToMany as OneToMany_} from "typeorm"
22
import {FarmCertification} from "./_farmCertification"
33
import {PublicIp} from "./publicIp.model"
44

@@ -14,12 +14,15 @@ export class Farm {
1414
@Column_("int4", {nullable: false})
1515
gridVersion!: number
1616

17+
@Index_()
1718
@Column_("int4", {nullable: false})
1819
farmID!: number
1920

21+
@Index_()
2022
@Column_("text", {nullable: false})
2123
name!: string
2224

25+
@Index_()
2326
@Column_("int4", {nullable: false})
2427
twinID!: number
2528

@@ -35,6 +38,7 @@ export class Farm {
3538
@Column_("text", {nullable: true})
3639
stellarAddress!: string | undefined | null
3740

41+
@Index_()
3842
@Column_("bool", {nullable: true})
3943
dedicatedFarm!: boolean | undefined | null
4044
}

src/model/generated/nameContract.model.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {Entity as Entity_, Column as Column_, PrimaryColumn as PrimaryColumn_} from "typeorm"
1+
import {Entity as Entity_, Column as Column_, PrimaryColumn as PrimaryColumn_, Index as Index_} from "typeorm"
22
import * as marshal from "./marshal"
33
import {ContractState} from "./_contractState"
44

@@ -14,15 +14,18 @@ export class NameContract {
1414
@Column_("int4", {nullable: false})
1515
gridVersion!: number
1616

17+
@Index_()
1718
@Column_("numeric", {transformer: marshal.bigintTransformer, nullable: false})
1819
contractID!: bigint
1920

21+
@Index_()
2022
@Column_("int4", {nullable: false})
2123
twinID!: number
2224

2325
@Column_("text", {nullable: false})
2426
name!: string
2527

28+
@Index_()
2629
@Column_("varchar", {length: 11, nullable: false})
2730
state!: ContractState
2831

src/model/generated/node.model.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {Entity as Entity_, Column as Column_, PrimaryColumn as PrimaryColumn_, ManyToOne as ManyToOne_, Index as Index_, OneToMany as OneToMany_} from "typeorm"
1+
import {Entity as Entity_, Column as Column_, PrimaryColumn as PrimaryColumn_, Index as Index_, ManyToOne as ManyToOne_, OneToMany as OneToMany_} from "typeorm"
22
import * as marshal from "./marshal"
33
import {Location} from "./location.model"
44
import {PublicConfig} from "./publicConfig.model"
@@ -19,12 +19,15 @@ export class Node {
1919
@Column_("int4", {nullable: false})
2020
gridVersion!: number
2121

22+
@Index_()
2223
@Column_("int4", {nullable: false})
2324
nodeID!: number
2425

26+
@Index_()
2527
@Column_("int4", {nullable: false})
2628
farmID!: number
2729

30+
@Index_()
2831
@Column_("int4", {nullable: false})
2932
twinID!: number
3033

@@ -52,6 +55,7 @@ export class Node {
5255
@OneToMany_(() => Interfaces, e => e.node)
5356
interfaces!: Interfaces[]
5457

58+
@Index_()
5559
@Column_("varchar", {length: 9, nullable: true})
5660
certification!: NodeCertification | undefined | null
5761

src/model/generated/nodeContract.model.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {Entity as Entity_, Column as Column_, PrimaryColumn as PrimaryColumn_, ManyToOne as ManyToOne_, Index as Index_} from "typeorm"
1+
import {Entity as Entity_, Column as Column_, PrimaryColumn as PrimaryColumn_, Index as Index_, ManyToOne as ManyToOne_} from "typeorm"
22
import * as marshal from "./marshal"
33
import {ContractState} from "./_contractState"
44
import {ContractResources} from "./contractResources.model"
@@ -15,12 +15,15 @@ export class NodeContract {
1515
@Column_("int4", {nullable: false})
1616
gridVersion!: number
1717

18+
@Index_()
1819
@Column_("numeric", {transformer: marshal.bigintTransformer, nullable: false})
1920
contractID!: bigint
2021

22+
@Index_()
2123
@Column_("int4", {nullable: false})
2224
twinID!: number
2325

26+
@Index_()
2427
@Column_("int4", {nullable: false})
2528
nodeID!: number
2629

@@ -33,6 +36,7 @@ export class NodeContract {
3336
@Column_("int4", {nullable: false})
3437
numberOfPublicIPs!: number
3538

39+
@Index_()
3640
@Column_("varchar", {length: 11, nullable: false})
3741
state!: ContractState
3842

src/model/generated/publicIp.model.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export class PublicIp {
1818
@Column_("text", {nullable: false})
1919
gateway!: string
2020

21+
@Index_()
2122
@Column_("text", {nullable: false})
2223
ip!: string
2324

src/model/generated/rentContract.model.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {Entity as Entity_, Column as Column_, PrimaryColumn as PrimaryColumn_} from "typeorm"
1+
import {Entity as Entity_, Column as Column_, PrimaryColumn as PrimaryColumn_, Index as Index_} from "typeorm"
22
import * as marshal from "./marshal"
33
import {ContractState} from "./_contractState"
44

@@ -14,15 +14,19 @@ export class RentContract {
1414
@Column_("int4", {nullable: false})
1515
gridVersion!: number
1616

17+
@Index_()
1718
@Column_("numeric", {transformer: marshal.bigintTransformer, nullable: false})
1819
contractID!: bigint
1920

21+
@Index_()
2022
@Column_("int4", {nullable: false})
2123
twinID!: number
2224

25+
@Index_()
2326
@Column_("int4", {nullable: false})
2427
nodeID!: number
2528

29+
@Index_()
2630
@Column_("varchar", {length: 11, nullable: false})
2731
state!: ContractState
2832

src/model/generated/twin.model.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {Entity as Entity_, Column as Column_, PrimaryColumn as PrimaryColumn_} from "typeorm"
1+
import {Entity as Entity_, Column as Column_, PrimaryColumn as PrimaryColumn_, Index as Index_} from "typeorm"
22

33
@Entity_()
44
export class Twin {
@@ -12,6 +12,7 @@ export class Twin {
1212
@Column_("int4", {nullable: false})
1313
gridVersion!: number
1414

15+
@Index_()
1516
@Column_("int4", {nullable: false})
1617
twinID!: number
1718

0 commit comments

Comments
 (0)