Skip to content
Row vs Column Storage
step 1/5

Reading — step 1 of 5

Read

~1 min readWhy Columnar

Row vs Column Storage

OLTP databases (Postgres, MySQL) store data ROW by row:

[row1: id=1, name=Alice, age=30]
[row2: id=2, name=Bob,   age=25]
[row3: id=3, name=Carol, age=35]

Reading a single row = read 1 disk block. Inserting a row = append 1 record. Great for transactional workloads.

OLAP / analytics workloads ask different questions: "what's the average age?" "how many users in each region?" — these scan many rows, but only a FEW columns.

Row layout problem: to compute avg(age), you scan ALL columns of all rows (id, name, age), wasting I/O on columns you don't need.

Column store lays out data by column:

id:   [1, 2, 3, ...]
name: [Alice, Bob, Carol, ...]
age:  [30, 25, 35, ...]

Each column = a separate file. Scanning age = read just one file. Massive I/O reduction.

Other benefits:

  • Compression: same-type values cluster well. Ages are 0-120 (1 byte each). Strings repeat → dictionary encoding shrinks 100x.
  • Vectorization: process arrays of values at once with SIMD.
  • Late materialization: filter on cheap columns first, only fetch others for survivors.

Trade-offs:

  • Inserts are expensive: each row touches N column files.
  • Updates: rewrite a column = rewrite all values (or use update files).
  • Single-row read: must read N column files → expensive.

Hence column stores are read-mostly. Insert in BATCH (millions of rows at once); appender writes columnar files.

Real systems: Apache Parquet, ClickHouse, Snowflake, BigQuery, Redshift, DuckDB, Vertica, Amazon Redshift, Google Bigtable variants.

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…