perf(db): add owner-prefixed hot-path indexes on JobApplications
Add composite indexes (OwnerUserId, IsDeleted) — for the tenant-scoped list/board/stats/analytics queries that all filter !IsDeleted — and (OwnerUserId, FollowUpAt) for the reminders surface. Every JobApplication query is scoped by the OwnerUserId global filter first, so owner-prefixed composites are the useful shape; the pre-existing single OwnerUserId index is now a redundant prefix but kept to avoid churn. Status is intentionally excluded: Pomelo maps the unbounded string column to MariaDB longtext, which cannot be indexed without a prefix length. Applied via the startup schema reconciler (StartupInitializationExtensions), which is how this repo actually provisions schema/indexes on both providers (SQLite: CREATE INDEX IF NOT EXISTS; MariaDB: MySqlIndexExists-guarded CREATE INDEX) — NOT via EF migrations, whose committed ModelSnapshot is stale. OnModelCreating also declares the indexes for model consistency. Backend suite: 92/92 green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -55,6 +55,20 @@ namespace JobTrackerApi.Data
|
||||
modelBuilder.Entity<JobApplication>()
|
||||
.HasIndex(j => j.OwnerUserId);
|
||||
|
||||
// Owner-prefixed composite indexes for the tenant-scoped hot paths. Every
|
||||
// JobApplication query is scoped by the OwnerUserId global filter first, then
|
||||
// filtered by IsDeleted (list/board/stats/analytics) or FollowUpAt (reminders).
|
||||
// Status is intentionally excluded from the index because Pomelo maps the
|
||||
// unbounded string column to longtext, which MariaDB cannot index without a
|
||||
// prefix length. The actual index DDL is applied idempotently in
|
||||
// StartupInitializationExtensions (this repo provisions schema via that
|
||||
// reconciler, not via the EF ModelSnapshot, which is stale).
|
||||
modelBuilder.Entity<JobApplication>()
|
||||
.HasIndex(j => new { j.OwnerUserId, j.IsDeleted });
|
||||
|
||||
modelBuilder.Entity<JobApplication>()
|
||||
.HasIndex(j => new { j.OwnerUserId, j.FollowUpAt });
|
||||
|
||||
modelBuilder.Entity<Company>()
|
||||
.HasIndex(c => c.OwnerUserId);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user