Course contents
On this page
Choose a plan using an estimate, then check it
See how correlated conditions can make a small-result estimate badly wrong.
After finding legal query plans, the engine needs to choose one. It might follow an index for a few matching rows or scan a large part of the table. It must usually choose before it knows exactly how many rows will match.
A planner uses statistics and a cost model to estimate that work. Statistics summarize stored data; a cost model translates estimated rows, pages, and other operations into comparable costs. Those costs need not be milliseconds.
Count rows under an assumption
Our shop has 10,000 customers. Of them, 1,000 live in region R and 1,000 use currency C. A query requires both conditions.
If the two properties were independent, the estimate would be:
Independent means that knowing one property does not change the probability of the other. Here that is a modeling assumption, not a fact established by the two separate counts.
Independent model
Region R: 1,000 customers
Expected fraction also using C: 10%
Estimated intersection: 100
Actual correlated data
All 1,000 customers in R use C
Actual intersection: 1,000
Estimate is ten times too small
The number of rows is cardinality. The fraction surviving a condition is selectivity. An underestimated cardinality can make repeated indexed lookups seem cheaper than a scan, or make an in-memory join appear to fit when it will need temporary storage.
Explain the mistaken choice
Imagine an illustrative cost model: scanning costs 500 units; fetching each qualifying row through an index costs one unit, plus 20 units of setup. At 100 expected matches, the index costs 120, so it wins. At 1,000 actual matches, that estimate becomes 1,020, exceeding the scan cost.
These numbers are invented to expose the decision boundary. A real model must account for caching, row placement, output width, and operator behavior. It should not assume that every row fetch has a constant physical cost.
Statistics can become stale or fail to capture relationships between columns. Better joint statistics may improve this example, but no summary predicts every future query perfectly.
Locate the break-even point
In the same illustrative model, how many qualifying rows make the index cost equal to the scan’s 500 units?
Include the setup cost
480 rows: 20 + 480 = 500. Below that point the index has lower estimated cost; above it the scan does. This compares only the stated model, not measured database timings.
When diagnosing a plan, compare estimated and observed rows at the first place they diverge. That is often more informative than blaming the final expensive operator alone.
PostgreSQL’s statistics documentation describes how estimates are supported, including statistics for related columns. EXPLAIN exposes estimates and, when requested, actual execution measurements.
Extended reference
The extended chapter preserves the original technical coverage, additional examples, and citations. The explanation above supplies the concepts needed for this page; the reference develops the specialist cases.
Find a section from the original chapter
- Learning outcomes
- A bad estimate selects a good algorithm for the wrong input
- Cardinality and selectivity
- Statistics are sampled and time-dependent
- Cost units and physical properties
- Join-order search
- Parameter sensitivity and plan caching
- Adaptive execution
- Reading evidence from a plan
- Derive an equality estimate and expose its assumptions
- Sampling has predictable blind spots
- Cost a scan and an index path without inventing milliseconds
- Dynamic programming retains alternatives with different properties
- A memory threshold can reverse the preferred plan
- Plan caching needs a distribution-aware policy
- Interpret actual rows together with loops
- Adaptation requires a safe handoff
- Compare competing plans under estimated and observed inputs
- Design conclusion
- Sources and further reading