SQL · Queries that survive scale
How do you approach SQL performance tuning?
Short answer
Measure the slow query, read its plan, reduce the rows and work it performs, add or fix indexes, and rewrite non-sargable predicates. Verify each change with realistic data.
Start with the actual query and its plan, not with guesses. Find the expensive node, compare estimated and actual rows, and check whether the query reads far more data than it returns. Fixing row estimates or removing a bad join often matters more than adding another index.
EXPLAIN (ANALYZE, BUFFERS)
SELECT o.id, o.total_cents
FROM orders o
JOIN customers c ON c.id = o.customer_id
WHERE c.email = 'a@example.com'
AND o.created_at >= now() - interval '30 days';The tuning checklist
- Confirm the query is actually the bottleneck and measure with realistic parameters
- Read the plan for sequential scans, bad estimates, spills, and repeated inner loops
- Reduce rows early with selective predicates and avoid functions on indexed columns
- Create composite indexes that match equality, range, and ordering needs
- Avoid N plus one access patterns and unnecessary SELECT * columns
- Use keyset pagination instead of deep OFFSET
- Refresh statistics and consider partitioning for very large tables
- Cache or precompute results when the same expensive aggregation is requested often
SELECT id, total_cents
FROM orders
WHERE customer_id = 42
AND created_at >= '2026-09-01'
AND created_at < '2026-10-01';Indexes are not the only lever. A query that returns a million rows to the application is a design problem, not an index problem. Sometimes the best fix is a narrower projection, a precomputed summary, or a different access pattern.
Follow-ups you should expect
Interviewers use these to check whether the first answer was understanding or memorisation.
- 1What does a sequential scan in the plan tell you?
- 2Why are functions on indexed columns a problem?
- 3How do you decide between an index and a precomputed summary?
- 4What metrics would you monitor after a tuning change?
Say it in the interview
I start by measuring the slow query and reading its plan, looking for expensive scans, bad row estimates, spills, and repeated work. Then I reduce the rows processed, fix non-sargable predicates, and add indexes that match the actual filter and sort order. I verify each change with realistic data because an index can help reads but hurt writes. If the query returns too much data by design, I change the access pattern rather than forcing another index.
Use this as a model, not a script. Saying it in your own words is what makes it survive follow-up pressure.
Related questions
Reading is step one
Now say it out loud.
Understanding an answer and delivering it under pressure are different skills. Rehearse this topic in a live SQL mock interview and get scored feedback on depth, clarity and confidence.