Analyse and optimise a slow database query — identify N+1 issues, missing indexes, inefficient joins, unbounded result sets, and generate index migrations
Analyse and optimise a slow or inefficient database query. Suggest indexes, query restructuring, caching, or schema changes.
Use $ARGUMENTS to determine:
Read the relevant repository, service, and entity before analysing.
Locate the actual SQL being executed:
@Query annotations — read the JPQL/SQL directly.Suggest running EXPLAIN ANALYZE on the query and look for:
N+1 Queries:
JOIN FETCH or @EntityGraph.Missing Indexes:
Unnecessary Data Loading:
Inefficient Joins:
Pagination Without Efficient Counting:
SELECT COUNT(*) on the full dataset every page request.Large Result Sets:
For each issue:
## Query Optimisation Report
### Current Performance
- Query: [The query being analysed]
- Estimated execution time: [if known]
- Issues identified: [count]
### Issues Found
#### Issue 1: [Description]
**Impact:** [HIGH | MEDIUM | LOW]
**Root cause:** [Explanation]
**Fix:** [Specific code/SQL change]
**Expected improvement:** [Estimate]
### Recommended Index Changes
[SQL for new indexes with rationale]
### Migration File (if schema changes needed)
[Complete Flyway migration]
### Updated Code
[Complete updated repository/service code]
CREATE INDEX idx_invoices_tenant_status ON invoices (tenant_id, status);
-- Rationale: The list endpoint filters by tenant_id and status on every request.
// Before: N+1 — loads customer for each invoice
List<Invoice> invoices = invoiceRepository.findByTenantId(tenantId);
// After: Single query with JOIN FETCH
@Query("SELECT i FROM Invoice i JOIN FETCH i.customer WHERE i.tenantId = :tenantId")
List<Invoice> findByTenantIdWithCustomer(@Param("tenantId") String tenantId);