DuckDB 61,228 splits a table into row groups of up to 122,880 rows, and stores each column of a row group as its own compressed column segment in 256 kB blocks. pragma_storage_info lists them:
SELECT row_group_id AS rg, column_name, segment_type, count, compression,
block_id, block_offset
FROM pragma_storage_info('sales')
WHERE column_name IN ('genre', 'gross_amount') AND segment_type <> 'VALIDITY'
ORDER BY rg, column_name;Output
┌───────┬──────────────┬───────────────┬────────┬─────────────┬──────────┬──────────────┐ │ rg │ column_name │ segment_type │ count │ compression │ block_id │ block_offset │ │ int64 │ varchar │ varchar │ int64 │ varchar │ int64 │ int64 │ ├───────┼──────────────┼───────────────┼────────┼─────────────┼──────────┼──────────────┤ │ 0 │ genre │ VARCHAR │ 122880 │ Dictionary │ 39 │ 92456 │ │ 0 │ gross_amount │ DECIMAL(10,2) │ 122880 │ BitPacking │ 35 │ 0 │ │ 1 │ genre │ VARCHAR │ 15064 │ Dictionary │ 40 │ 73520 │ │ 1 │ gross_amount │ DECIMAL(10,2) │ 15064 │ BitPacking │ 40 │ 105928 │ └───────┴──────────────┴───────────────┴────────┴─────────────┴──────────┴──────────────┘
The first row group's 122,880 genres sit together in one segment, away from the amounts; a validity segment per column (filtered out here) records NULLs. Each segment has its own compression and statistics. Row groups are the unit of parallelism and skipping (Zone Maps and Pruning), segments the unit of reading: Parquet 129 's plan (Row Groups and Pages), plus updates, a write-ahead log and transactions.