liveBook · Manning

Index-only scan

As explained in PostgreSQL Mistakes and How to Avoid Them

An index-only scan answers a query from index contents without needing to fetch the corresponding table rows when visibility information permits.

An index-only scan answers a query using index contents instead of fetching table rows. It is especially effective when the query selects only indexed columns and its predicates match the index. section 2.9 section 1.5.2

Counting open tickets

A sequential scan counts 250 open tickets in about 110 ms. Adding an index on status changes the plan to an Index Only Scan and reduces the query to about 3.7 ms. Because only status = 10 matters and open tickets represent roughly 0.05% of the table, a partial index with WHERE status = 10 shrinks the index from 3408 kB to 16 kB and reduces execution to about 0.8 ms. section 1.5.2

Use the execution plan to verify whether the optimization is actually helping:

  • Run EXPLAIN before and after creating the index; look for Index Only Scan rather than Seq Scan. section 1.5.2 section 6.10
  • Select only indexed columns when possible. Adding non-indexed columns makes PostgreSQL fetch table rows, producing an Index Scan instead. section 2.9
  • Prefer a partial index when the query repeatedly targets a small, stable subset; smaller indexes reduce traversal, disk use, and write-update work. section 1.5.2
  • Do not assume a foreign key creates an index on its referencing column; adding one can convert a sequential scan into an index-only scan. section 6.10
                                  QUERY PLAN
----------------------------------------------------------------------------
 Aggregate  (cost=4.16..4.17 rows=1 width=8)
   ->  Index Only Scan using tickets_status_idx on tickets
   (cost=0.14..4.16 rows=1 width=0)
(2 rows)

Inspect the compact plan produced by the partial index and confirm that the count uses an Index Only Scan. section 1.5.2

How PostgreSQL Mistakes and How to Avoid Them covers it

How deep it goes
Explains plan diagnosis, column-selection effects, partial indexes, and foreign-key indexing, but does not detail visibility-map internals.
Examples
Uses open-ticket counts, invoice counts by customer, EXPLAIN output, and Python comparisons between selecting identifiers and all columns.
What it assumes
Assumes basic SQL, indexes, WHERE clauses, joins, and EXPLAIN while reinforcing why foreign-key columns may need explicit indexes.
What you can do after
Diagnose with EXPLAIN whether indexing changes a sequential scan into an index-only scan and choose a narrower partial index when appropriate.
How it connects
Connects indexes with sequential scans, partial indexes, query plans, foreign keys, subqueries, and common table expressions.

Also explained in

Compare how 2 books explain index-only scan →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of PostgreSQL Mistakes and How to Avoid Them. The section links point to the parts of the book it draws on.