> **Seq Scan** > <table> > <tr> > <td width="25%"><img src="assets/ex_seqscan.png"></td> > <td>The engine's most fundamental access path. It reads every page in the relation sequentially, loading them into Shared Buffers to check every tuple against the filter criteria. While linearly dependent on table size, it is the most robust option for low-selectivity queries or unindexed columns.</td> > </tr> > </table> > > ```sql > -- Querying the entire animals table > EXPLAIN (ANALYZE, COSTS, BUFFERS, VERBOSE) > SELECT * FROM animals; > ``` > > ![SeqScan Plan Tree](assets/plan_tree_op_seq_scan.svg) > > <!-- literal-explain-plan > Captured EXPLAIN provenance for the adjacent reader-facing visual plan. > Canonical capture metadata lives in scratch/actual_operation_plans.json. > > Seq Scan on public.animals (cost=0.00..174.00 rows=10000 width=27) (actual time=0.006..0.359 rows=10000 loops=1) > Output: id, name, species_id, created_at > Buffers: shared hit=74 > Planning: > Buffers: shared hit=73 > Planning Time: 0.361 ms > Execution Time: 0.600 ms > --> > > > <!-- > Raw-capture provenance — separate run. > SQL, setup, dataset, settings, and scope: artifacts/chapter4_capture_matrix.json. > Target: PostgreSQL 18.x companion fixture. Cache state: uncontrolled. > Boundary: pg_wait_tracer backend execution root; client states are included when the chart shows them. > Fidelity: exact pg_wait_tracer export. Not the adjacent EXPLAIN run; compare state shape, not durations. > --> > > ![Seq Scan separate raw capture](assets/trace_op_seq_scan.svg) > > <table> > <tr> > <td rowspan="2" width="25%"><img src="assets/ex_scan.svg"></td> > <td><b>Performance</b></td><td>Scans the entire table, can be slow.</td> > </tr> > <tr><td><b>Cost</b></td><td><code>disk I/O cost * table size</code></td></tr> > </table>