Sequential scan
What is a sequential scan in PostgreSQL?
A sequential scan reads every row of a table from start to end. EXPLAIN shows it as Seq Scan; it is the normal choice for small tables or queries that return many rows.
A sequential scan (Seq Scan in EXPLAIN output) reads all of a table's pages in order and checks every row against the query's conditions. It needs no index, and it is what the planner falls back on when no usable index exists.
A Seq Scan is not automatically a problem. For small tables, or when a query returns a large share of the rows, reading the whole table can be cheaper than jumping back and forth between an index and the table. It becomes a concern when a large table is read in full to return a handful of rows; an index on the filtered column usually fixes that. The planner decides based on table statistics, so run ANALYZE after loading a lot of data.
Example
The example loads 100,000 rows, collects statistics with ANALYZE and asks EXPLAIN how PostgreSQL would filter on a column without an index. The output shows Seq Scan on events.
CREATE TABLE events (id int, kind text);
INSERT INTO events
SELECT g, 'k' || (g % 10) FROM generate_series(1, 100000) AS g;
ANALYZE events;
EXPLAIN SELECT * FROM events WHERE kind = 'k3';Plain SQL for stock PostgreSQL 16 or 17, no extensions needed. Run it in an empty database you can throw away.
Sources
Official PostgreSQL documentation (in English).