Implementing Query Optimization

1. Writing Efficient Queries

PracticeDetail
Project only needed columnsAvoid SELECT *
Filter earlyWHERE before JOIN where possible
Use indexesMatch leading columns
Limit rowsLIMIT/pagination
Avoid functions on indexed colsBreaks index usage

2. Using Query Hints

EngineHint
Oracle/*+ INDEX(t idx) */
MySQLUSE INDEX(idx), STRAIGHT_JOIN
PostgreSQLpg_hint_plan extension
JPA@QueryHint for fetch size, timeout
Warning: Hints lock you into a plan; revisit when stats change.

3. Implementing Batch Fetching

MechanismDetail
Hibernate @BatchSizeGroup lazy loads into IN clause
JDBC setFetchSizeServer-side cursor
Spring Data EntityGraphEager fetch specific paths

4. Implementing Query Result Caching

LayerTool
AppCaffeine, @Cacheable
ORMHibernate 2nd-level + query cache
DistributedRedis
DBMaterialized views

5. Implementing N+1 Query Prevention

Example: JOIN FETCH

// BAD: orders.forEach(o -> o.getLines())  // each triggers a query
// GOOD:
@Query("select o from Order o join fetch o.lines where o.status = :s")
List<Order> findOpenWithLines(@Param("s") String status);

6. Implementing Projection Queries

Example: DTO projection

@Query("select new com.acme.OrderSummary(o.id, o.totalCents) from Order o where o.status = :s")
List<OrderSummary> summarize(@Param("s") String status);

7. Implementing Native Queries

UseDetail
DB-specific featuresJSONB, window functions, CTEs
PerformanceHand-tuned SQL
JPA@Query(nativeQuery=true)
Trade-offLoses portability

8. Analyzing Query Execution Plans

ToolCommand
PostgreSQLEXPLAIN (ANALYZE, BUFFERS) ...
MySQLEXPLAIN ANALYZE ... (8.0+)
OracleEXPLAIN PLAN FOR ...
Look forSeq Scan on big table, mismatched estimates

9. Optimizing Subqueries

PatternReplacement
Correlated subqueryJOIN or LATERAL
IN (subquery)EXISTS or JOIN
Repeated subqueryCTE / temp table

10. Using Criteria API

Example: Type-safe Criteria

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Order> q = cb.createQuery(Order.class);
Root<Order> root = q.from(Order.class);
q.select(root).where(cb.equal(root.get("status"), "OPEN"));
em.createQuery(q).getResultList();

11. Implementing Query Pagination

StyleDetail
OffsetSlow for large offsets
Keyset (seek)WHERE (placed_at, id) < (?, ?) ORDER BY ... LIMIT n
Window functionROW_NUMBER() OVER ...

12. Implementing Query Indexing Strategy

StepDetail
Profile real workloadpg_stat_statements
Match WHERE/JOIN/ORDERComposite index columns in that order
Cover hot SELECTsINCLUDE non-key columns
Drop unusedpg_stat_user_indexes idx_scan = 0
Beware write costEach index slows INSERT/UPDATE