# 3.2.3 The Prep Station (Aggregations) ![The Prep Station](assets/arch_prep_station.png) With data fetched by the Pantry Fetchers and combined by the Sous Chefs, the final step in the Query Algebra is usually shaping the output for the Maitre D'. This falls to **The Prep Station**, a dedicated area where ingredients are **squashed**, **sorted**, and **summarized**. ### The Maitre D's Summary Let's see how the Prep Station squashes our Cafe's data for the Maitre D'. #### 1. The Prep Bucket (HashAggregate) If the ingredients aren't sorted, the Prep Station staff member has to throw them into buckets (a Hash Table) on their Counter. This requires a lot of memory! ```sql -- Squashing 10 million individual deliveries into totals per ingredient EXPLAIN SELECT ingredient_id, sum(quantity_kg) FROM supply_deliveries GROUP BY ingredient_id; -- Result (The Bucket Toss): -- HashAggregate (cost=105.30..106.55 rows=100 width=36) -- Group Key: ingredient_id > [!TIP] > **Elephant's Footnote: The Memory Bucket** > - **`rows=100`**: The Head Chef expects to find 100 unique ingredients. > - **`HashAggregate`**: Because the data is unsorted, the staff must build 100 buckets in memory. If they run out of space (`work_mem`), they start spilling into the Frozen Pantry! ``` #### 2. The Sorting Bench (GroupAggregate) Once the ingredients arrive at the Prep Station already sorted (via an Index), the staff member just stands there with a clicker and watches them pass by! This is incredibly efficient. ```sql -- The ingredients arrive already prepped (sorted) CREATE INDEX idx_supply_ingredient ON supply_deliveries(ingredient_id); EXPLAIN SELECT ingredient_id, sum(quantity_kg) FROM supply_deliveries GROUP BY ingredient_id; -- Result (The Clicker Pass): -- GroupAggregate (cost=0.28..110.19 rows=100 width=36) -- Group Key: ingredient_id > [!TIP] > **Elephant's Footnote: The Sorted Flow** > - **`GroupAggregate`**: Since the ingredients are already sorted by ID (thanks to the Index), the staff member just stands there and clicks their counter. No buckets required! ``` #### 3. The Portion Controller (Limit) This is the Head Chef's favorite way to save energy at the Prep Station. If the Maitre D' only needs one plate, why fetch ten million? ```sql EXPLAIN SELECT * FROM supply_deliveries LIMIT 1; -- Result: -- Limit (cost=0.00..0.02 rows=1 width=44) -- -> Seq Scan on supply_deliveries (cost=0.00..1845.00 rows=10000000) ``` Notice the **`cost`** at the top! Even though the fetch below it costs 1,845 points, the **Limit** node knows it only needs one item. It pulls the plug on the Pantry Fetcher the moment it gets what it wants! --- | ← Previous | ↑ Table of Contents | Next → | | :--- | :---: | ---: | | [[Chapter 3/3.2.2 - The Matchmakers (Joins)\|3.2.2 The Matchmakers (Joins)]] | [[Learn You a Postgres for Great Good\|Home]] | [[Chapter 3/3.3 - The Art of Not Opening Every Box (Sargability)\|3.3 The Art of Not Opening Every Box (Sargability)]] |