SQL · Queries that survive scale

What is a correlated subquery and how does it perform?

Hardcorrelated subqueriesperformancequery plansUpdated Oct 2026
Quiz this track

Short answer

A correlated subquery references columns from the outer query, so conceptually it is evaluated per outer row. Optimizers can decorrelate many cases, but the plan must be checked.

The correlation is the reference to an outer column inside the subquery. That reference ties the subquery to each candidate row, which is why correlated subqueries are often described as running once per outer row.

sql
SELECT e.id, e.name, e.salary
FROM employees e
WHERE e.salary > (
  SELECT AVG(x.salary)
  FROM employees x
  WHERE x.department_id = e.department_id
);
Each employee is compared with the average salary of their own department.

How engines handle them

  • A naive plan runs the subquery for every outer row, which becomes expensive
  • Optimizers can decorrelate into a join or a window function
  • An index on the correlation column, here department_id, helps the naive plan
  • EXISTS and IN are often decorrelated into semi-joins
  • A window function can express the same logic in one pass

The equivalent window-function form partitions by department and computes the average once. It is often easier for the planner to execute efficiently, but it is not always faster, so compare plans on realistic data.

sql
WITH ranked AS (
  SELECT id, name, salary,
         AVG(salary) OVER (PARTITION BY department_id) AS dept_avg
  FROM employees
)
SELECT id, name, salary
FROM ranked
WHERE salary > dept_avg;
Do not assume every correlated subquery is slow. A correlated EXISTS with a selective index can be extremely fast. The plan and row estimates decide.

Follow-ups you should expect

Interviewers use these to check whether the first answer was understanding or memorisation.

  1. 1How would you rewrite this with a window function?
  2. 2When does a correlated subquery become a performance problem?
  3. 3What does decorrelation mean?
  4. 4Why can an index on the correlation column help?

Say it in the interview

A correlated subquery references a column from the outer query, so logically it depends on each outer row. A naive execution runs it repeatedly, which can be expensive. Modern optimizers often decorrelate it into a join or a window operation, so I check the plan rather than assuming. I also consider rewriting it with a window function when the same aggregate is needed across partitions.

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.