Merge pull request #347 from Hestia-Homes/reporting-slow-query

perf(db): index the EPC-graph FK columns hammering reporting
This commit is contained in:
Jun-te Kim 2026-07-02 14:45:40 +01:00 committed by GitHub
commit 32bf005c80
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 11789 additions and 0 deletions

View file

@ -0,0 +1,4 @@
CREATE INDEX CONCURRENTLY "ix_epc_building_part_epc_property" ON "epc_building_part" USING btree ("epc_property_id");--> statement-breakpoint
CREATE INDEX CONCURRENTLY "ix_epc_energy_element_epc_property" ON "epc_energy_element" USING btree ("epc_property_id");--> statement-breakpoint
CREATE INDEX CONCURRENTLY "ix_epc_floor_dimension_building_part" ON "epc_floor_dimension" USING btree ("epc_building_part_id");--> statement-breakpoint
CREATE INDEX CONCURRENTLY "ix_property_portfolio" ON "property" USING btree ("portfolio_id");

File diff suppressed because it is too large Load diff

View file

@ -1793,6 +1793,13 @@
"when": 1782989713551,
"tag": "0256_glazing_secondary",
"breakpoints": true
},
{
"idx": 257,
"version": "7",
"when": 1782999533851,
"tag": "0257_low_songbird",
"breakpoints": true
}
]
}

View file

@ -174,6 +174,10 @@ export const property = pgTable(
uniqueIndex("uq_property_portfolio_uprn")
.on(table.portfolioId, table.uprn)
.where(sql`${table.uprn} IS NOT NULL`),
// Plain `portfolio_id = ?` filters (reporting, portfolio list) — the
// partial unique above only covers rows WHERE uprn IS NOT NULL, so the
// planner can't use it for these.
index("ix_property_portfolio").on(table.portfolioId),
],
);
@ -782,6 +786,11 @@ export const epcBuildingPart = pgTable(
altWall2InsulationThickness: text("alt_wall_2_insulation_thickness"),
altWall2IsSheltered: boolean("alt_wall_2_is_sheltered"), // nullable (null when no alt wall)
},
(table) => [
// Per-EPC part lookups: the reporting age-band subquery and the
// condition-report / descriptor resolvers all filter on epc_property_id.
index("ix_epc_building_part_epc_property").on(table.epcPropertyId),
],
);
// ─── epc_floor_dimension ──────────────────────────────────────────────────────
@ -804,6 +813,11 @@ export const epcFloorDimension = pgTable(
isExposedFloor: boolean("is_exposed_floor").notNull().default(false),
isAbovePartiallyHeatedSpace: boolean("is_above_partially_heated_space").notNull().default(false),
},
(table) => [
// Condition-report floor-height/storey lookups fetch all dimensions for
// one building part.
index("ix_epc_floor_dimension_building_part").on(table.epcBuildingPartId),
],
);
// ─── epc_window ───────────────────────────────────────────────────────────────
@ -870,6 +884,10 @@ export const epcEnergyElement = pgTable(
energyEfficiencyRating: integer("energy_efficiency_rating").notNull(),
environmentalEfficiencyRating: integer("environmental_efficiency_rating").notNull(),
},
(table) => [
// Condition-report fabric lookups fetch all elements for one EPC.
index("ix_epc_energy_element_epc_property").on(table.epcPropertyId),
],
);
// ─── epc_renewable_heat_incentive ─────────────────────────────────────────────