In this lesson, you will learn how PostgreSQL coordinates multiple background processes to speed up massive data scans and aggregations.
The Parallel Architecture
When a query is complex—such as a large SELECT involving heavy table scans or aggregations—PostgreSQL can decide to break the work into pieces. Instead of a single process doing everything, the Gather node is introduced.
The Gather node acts as the "orchestrator." It initiates a set of background Parallel Workers. These workers perform the heavy lifting (like sequential scans) simultaneously, operating on different segments of the table data in parallel.
Sharing the Load
How do these workers know what to do without bumping into each other? PostgreSQL uses a Parallel Heap Scan. Imagine a massive book (your table); the workers don't decide arbitrarily which pages to read. Instead, they access a shared memory area that keeps track of which blocks have already been scanned.
- The Lead Process: Starts the query and spawns the workers.
- The Workers: Request a block of data from the shared scan state. They process that block and then immediately request the next available one.
- The Merge: As workers finish their tasks, they stream the results back into a shared memory buffer. The Lead Process gathers these partial results and combines them into the final output.
A Quick Illustration
Consider this execution plan snippet:
Gather (cost=1000.00..2000.00 rows=500 width=8)
Workers Planned: 2
-> Parallel Seq Scan on sales
Filter: (amount > 1000)
Here, the Gather node tells the engine to start two background workers. Each worker performs a Parallel Seq Scan on the sales table. They each filter rows and pass the partial results back to the Gather node, which collects them into a single result set for the user. Because this happens in parallel, the wall-clock time for the query is significantly reduced compared to one process doing the work alone.
Key Takeaway: Parallel query execution uses a Gather node to orchestrate multiple background workers, which coordinate via shared memory to scan data in segments and merge partial results back into a unified output.