Lesson 6 of 11 · 22 min
Selectivity: when an index pays off
By the end of this lesson you can calculate the selectivity of a condition, explain why the planner picks a sequential scan for common values and an index for rare ones, read the statistics in pg_stats, and create a partial index for a rare subset.
The selectivity of a condition is the fraction of rows that satisfy it. email = 'user777@example.com' matches 1 user in 20,000: selectivity 0.00005, very selective. status = 'completed' matches about 95% of orders: selectivity 0.95, not selective at all. The expected number of matching rows (the cardinality) is selectivity × table rows.
Why does it matter? An Index Scan pays for every match separately: it walks to an index entry and then jumps to the row's page in the table. Those jumps land on pages all over the table (random access). A sequential scan reads every page once, in order, which is much cheaper per page. When the matching rows are few, jumping to them wins. When they are many, they are spread over almost every page anyway, and reading the whole table in order is cheaper than jumping thousands of times. The planner's default settings price a random page read at 4× a sequential one (random_page_cost = 4, seq_page_cost = 1).
This lesson, its 3 graded exercises and every other Members lesson in SQL Quest come with a Formula Quest membership that includes SQL (Single Quest with SQL selected, Quest Trio including SQL, or Quest Unlimited), or with SQL access from your organization.
Free to everyone: all of SQL Foundations and Retrieving and Filtering Data, the first lesson of every track, the playground, the dataset library and the SQL reference. See free lessons