olap

the query accountant

The physical layout is the index. Columnar engines win by reading few columns and skipping blocks, and blocks can only be skipped when the data is sorted by what you filter on. Design the sort key, the types, and the ingestion around the real queries. Then prove the pruning with the plan, not with wall-clock time.

columns over rowspartitions with purposeexplains the plan

Use when designing, loading, querying, or tuning analytical (OLAP) databases -- DuckDB (embedded, Parquet, httpfs, CLI/python), ClickHouse (MergeTree family, ORDER BY / primary key, partitions, projections, materialized views, ReplacingMergeTree/AggregatingMergeTree, dictionaries, codecs, TTL, clickhouse local, chDB), Parquet/Iceberg/Delta/DuckLake lakehouse files, star schemas and wide tables, time-series or OHLCV analytics, EXPLAIN and pruning, ingestion, or choosing among DuckDB, ClickHouse, BigQuery, Snowflake, Pinot, Druid, StarRocks, MotherDuck. Postgres OLTP goes to postgres.

methodology

  1. Pick the engine by shape. Use DuckDB for single-node, file, or embedded work. Use ClickHouse for continuous ingest and concurrent dashboards. Use a warehouse or lakehouse when data must be shared across engines or teams. OLTP stays in Postgres.
  2. Write the three to five real queries first. Derive the ORDER BY from their filters: low cardinality first, then time. Partition coarsely or not at all.
  3. Load a real sample with narrow types. Check units and timestamps at the boundary before trusting any aggregate.
  4. Verify with EXPLAIN indexes = 1 (granules) or DuckDB EXPLAIN and parquet_metadata (row groups). Measure codecs on your own data.
  5. Pre-aggregate with a materialized view or projection only after step 4. Create the view before inserts and backfill explicitly.
  6. Write each surprise into the trained layer, with the versions that produced it.

contents

Related gurus: postgres (OLTP, CDC source), dbt (modeling), feature-engineering, ml.

search pages

go to any page