N+1 Queries & Batching
Avoid hidden query multiplication in ORM-backed endpoints.
📌 Key IdeaN+1 happens when parent rows are fetched once, then each child relation is fetched individually. Fix with join fetch, entity graphs, or batched secondary queries.
Why It Matters
- N+1 silently destroys latency and database throughput as page size grows.
- It often passes local testing and appears only under realistic production load.
- Fixing it early reduces DB cost and prevents scaling bottlenecks.
Visual
? N+1 query explosion
1 query: SELECT * FROM orders LIMIT 50 +50 queries: SELECT * FROM items WHERE order_id = ? = 51 total (N+1)
When to Use
- Hibernate/JPA APIs returning parent+child views.
- Endpoints where query count spikes with page size.
When NOT to Use
- Blind eager fetching of huge graphs.
- Joining everything when only IDs are needed.
Code Variations
1?? Join fetch / entity graphjava
@Query("select o from Order o join fetch o.items where o.user.id = :uid")
List<Order> findOrdersWithItems(long uid);Preloads relation in one query for targeted use cases.
2?? Batch size hintjava
@BatchSize(size = 50)
@OneToMany(mappedBy = "order")
private List<OrderItem> items;Reduces N+1 to fewer grouped queries when join fetch not ideal.
Interview Q&A
Quick Cheat Sheet
SymptomQuery count grows linearly with result size.
Fixesjoin fetch, entity graph, batch fetch, DTO projection.
GuardrailQuery-count assertions in tests.