advanced26 min studyLesson 295 in Engineering

Project the columns the whole plan needs

Calculate required column unions, distinguish output selectivity from physical reads, and reason about page-level late materialization.

On this page

What you’ll understand

  • Build a required-column set including filters, joins, and output expressions.
  • Estimate logical projected bytes without promising proportional physical I/O.
  • Explain how late materialization depends on page navigation and row alignment.

A query that returns two columns may need several more to decide which rows to return. Column projection removes unused fields from a scan, but its correct scope is the whole relevant query plan, not only the final output list. Once required fields are known, an engine can consider when to decode them. These decisions connect logical queries to page ranges, temporary buffers, and CPU work, so each layer needs its own measurement.

Required fields are a union, not a count of outputs

Consider SELECT price FROM events WHERE region='west'. Even though the output has only price, the scan generally needs region to evaluate the predicate unless trustworthy partition or other metadata already establishes it. Joins, grouping keys, sort expressions, and user-defined computations can require further fields. Track the union of required leaf paths so a field used twice is not counted twice. For a nested object, retrieving one child may still need validity or structural information that describes its ancestors; the storage representation determines those dependencies.

After projection, the reader locates column chunks and pages for selected row groups. It can often avoid fetching unrelated field payload entirely, which is a central advantage of columnar layout. But projection does not eliminate file metadata, structural levels, page headers, dictionaries for selected fields, or extra bytes brought in by request coalescing. Large fixed-size remote reads can also deliver neighboring bytes. Record which bytes were requested and which were useful rather than assuming that two selected fields in a ten-field schema always produce exactly one-fifth of the transferred data.

Crequired=Coutput∪Cfilter∪Cjoin∪CotherC_{\rm required}=C_{\rm output}\cup C_{\rm filter}\cup C_{\rm join}\cup C_{\rm other}
The sets contain required source leaf-column paths after valid plan simplifications. Other includes grouping, sorting, or computed-expression dependencies. Set union avoids double counting; metadata may eliminate a dependency only when it soundly establishes the relevant semantics.↔ Scroll wide equations horizontally.

Late materialization avoids some work at physical granularity

An engine can evaluate selective filter columns first, produce matching row positions, and then fetch or decode other selected columns only where needed. This is late materialization. Its benefit depends on format navigation, engine support, page size, match distribution, and the cost of extra passes. A single matching row may still require decompressing the page containing it. If matches are scattered across every page, a one-percent result can still touch nearly all output-column pages, even while avoiding some value conversion or copying within them.

Page indexes and row-position information help align skips across columns with different page boundaries. They do not make every row independently compressed or randomly accessible at zero cost. Dictionary state may need to be loaded before a referenced data page can be interpreted, and nested fields add structural alignment requirements. Compare an eager scan and a staged scan on both clustered and scattered matches. Include all remote requests, decoder CPU, and intermediate position buffers so the chosen strategy improves the user's operation rather than only one internal counter.

Dlogical=N∑c∈Crequiredsc,Dfetched=Dmetadata+∑p∈Pfetchedbytes⁡(p)D_{\rm logical}=N\sum_{c\in C_{\rm required}}s_c,\qquad D_{\rm fetched}=D_{\rm metadata}+\sum_{p\in P_{\rm fetched}}\operatorname{bytes}(p)
The first formula assumes N rows of flat fixed-width nonnullable required columns with widths s_c bytes. The second counts actual fetched page/range payload plus metadata under a chosen non-overlapping accounting scheme. Compression, padding, and coalescing mean the two totals need not be proportional.↔ Scroll wide equations horizontally.

Less data movement can change the next bottleneck

A narrow projection can shift a scan from storage transfer toward decoding, memory bandwidth, or aggregation CPU. Once one layer improves, remeasure before applying the same optimization again. For an AI feature pipeline, unused string columns can be expensive both on storage and in materialized objects, while a compact numeric aggregation can become limited by arithmetic or memory movement. File compression ratio alone cannot diagnose this transition. Use end-to-end latency and per-stage counters with a fixed result check to locate the remaining cost.

The roofline lab concerns a hypothetical floating-point kernel after data has been decoded, not disk throughput or integer decoder speed. Reset, set both intensity I=4 FLOP/byte and memory bandwidth B=50 decimal GB/s, predict a 200 GFLOP/s ceiling, then Play or Step. Reset, re-enter both I=8 and B=50, predict 400 GFLOP/s, then inspect. The compute roof stays 1,000 GFLOP/s and playback only traces the roof. Projection may change a real kernel's bytes per useful operation, but the lab does not project a file or measure a scan.

Count a filter column that is not returned

One million flat nonnullable rows have one hundred eight-byte columns. A query returns two columns and filters using a third distinct column. No metadata eliminates the filter and no pruning occurs. Ignore encoding and headers.

  1. The whole table has 1,000,000 × 100 × 8 = 800,000,000 bytes of logical payload, or 800 decimal MB.

  2. The required union contains three columns, not two. Its logical scan payload is 1,000,000 × 3 × 8 = 24,000,000 bytes, or 24 MB.

  3. If only one percent of rows survives, the two output columns contain 10,000 × 2 × 8 = 160,000 bytes. That result size does not imply the filter and output pages required only 160,000 physical bytes to read.

The result

Projection reduces logical input payload from 800 MB to 24 MB in this simplified scan. Result selectivity and physical page skipping remain separate questions.

Explore the model

Interactive lab

Interactive lab · roofline

A projected numeric kernel can change bottlenecks

Reset, set both I=4 FLOP/byte and memory B=50 decimal GB/s, predict 200 GFLOP/s, then Play or Step. Reset and re-enter I=8 and B=50 to predict 400. The fixed synthetic compute roof is 1,000 GFLOP/s; playback traces it. This is a post-decode floating-point ceiling, not a storage or Parquet scan predictor.

A projected numeric kernel can change bottlenecksSynthetic roofline ceiling min(1000, B·I), in GFLOP/s, with B in decimal GB/s and I in FLOP/byte. Playback traces the roof without changing the selected kernel. This upper-bound model is not a measured throughput prediction, hardware comparison or price model. Current readings: Attainable ceiling: 640 GFLOP/s; Ridge intensity: 12.5 FLOP/byte; Ceiling regime: Memory-bound ceiling. All parameters are adjustable with the labeled controls below.Hypothetical roofline upper bound: 640 GFLOP per second at operational intensity 8 FLOP per byte and bandwidth 80 gigabytes per second.0.1110641101001000Operational intensity · FLOP/byte · log scaleCeiling · GFLOP/s · log scalePeak: 1000
Attainable ceiling / kernelBandwidth roof / traceCompute ceiling
Attainable ceiling
640 GFLOP/s
Ridge intensity
12.5 FLOP/byte
Ceiling regime
Memory-bound ceiling
t = 0 s

Synthetic roofline ceiling min(1000, B·I), in GFLOP/s, with B in decimal GB/s and I in FLOP/byte. Playback traces the roof without changing the selected kernel. This upper-bound model is not a measured throughput prediction, hardware comparison or price model. Parameter changes pause playback and recompute the model at the current elapsed time. Reset restores both parameters and returns time to zero. Playback starts paused. Adjust either parameter, then choose Play or Step.

Look forReducing bytes per useful operation can expose another bottleneck, but format I/O and computation need separate models.

Check your understanding

A query returns columns a and b but evaluates a filter on distinct column c without a metadata shortcut. Which logical column set is required at the scan?

Try it yourself

A query over 200,000 rows returns an eight-byte value and filters on a separate four-byte key. Estimate required logical input payload before pruning and explain why ten matching rows do not determine physical read bytes.

Take a moment to make a prediction or work it out on paper. Open a hint when you need one.

Give me a hint

Include both dependencies, then consider compressed page boundaries.

Compare with the solution

The required logical payload is 200,000 × (8 + 4) = 2,400,000 bytes before encoding, headers, and validity information. Ten result rows can be scattered across pages, and reading one value can require its containing page and dictionary. Filter pages and metadata are also needed, so result row count alone cannot determine physical bytes fetched.

Take it with you

  • Project the union of output and intermediate query dependencies.
  • Late materialization works at format and reader granularity rather than making every row an independent read.
  • Measure requested bytes, decoder work, and post-decode computation separately as bottlenecks move.

Read further

Original sources and deeper explanations to follow at your own pace.

Optional progress, saved in this browser when available. Revisit any lesson at any time.

Lesson not marked complete.