Partitioning removes files; clustering sharpens what remains
Separate partition transforms, directory conventions, and file statistics while choosing layout from representative query patterns and skew.
On this page
The question for today
What you’ll understand
- Derive a safe candidate partition set from a query predicate and transform.
- Explain how partition granularity interacts with file count and skew.
- Distinguish partition exclusion from row-group pruning and result filtering.
Partitioning organizes a dataset into subsets that a query can sometimes exclude before reading file contents. Clustering organizes values within those subsets to make finer summaries useful. Both are layout decisions made in anticipation of queries, not guarantees that every filter avoids work. A good design records how partitions derive from source values, handles skew and late arrivals, and keeps metadata trustworthy enough that excluded files cannot contain missing answers.
A partition key is a declared relationship
A directory named day=2026-01-05 is useful only if the reader knows its partition convention and the data actually satisfies that declaration. Partition fields can be materialized metadata rather than repeated payload columns. A table format can instead record a transform such as a day derived from a timestamp or a hash bucket derived from an identifier. Translate the query through that transform conservatively: equality on a source ID may select one known hash bucket, while an arbitrary range on IDs generally does not select a contiguous range of hash buckets.
Time boundaries need particular care. A day partition derived under one timezone or instant interpretation is not automatically compatible with a query expressed under another. A range spanning midnight can touch two or more partitions even if it is short. Missing, malformed, or stale partition metadata must not silently remove files from consideration. Keep the residual row filter after pruning, because a selected partition can contain many nonmatching rows. An engine's ability to infer partition values from paths is a reader feature and convention, not an inherent guarantee of every Parquet file.
Granularity trades exclusion against overhead
Partitioning by every high-cardinality request ID can create tiny files and expensive listings or metadata even if equality pruning looks attractive. Partitioning only by year may keep files large but retain too much data for common daily queries. Estimate the expected bytes and file count per active partition, including skewed tenants and late-arriving updates. A partition with one unusually large customer can dominate runtime while many others finish quickly. More partitions do not create parallel work proportional to their count if the data and tasks are severely unbalanced.
Within each partition, sorting or clustering by a frequent range key can tighten file or row-group min/max bounds. This complements partition pruning rather than replacing it. A daily partition might first exclude other days; a tenant or timestamp ordering can then reject irrelevant groups within that day. Sorting has a write and compaction cost, and one order cannot optimize every unrelated access pattern equally. Compare layouts with a workload of queries, maintenance, and ingestion, preserving identical answers instead of selecting the single query that makes a preferred layout look best.
Observe discovery cost as well as scan cost
A query can spend substantial time discovering files, reading manifests or footers, and scheduling tasks before useful data transfer begins. Table metadata can make candidate discovery cheaper than recursively listing a directory, but it introduces its own update and compatibility contracts. Repartitioning or compaction must publish the new file set consistently so readers do not see both old and replacement data or neither. Save old generations long enough for active snapshots and the retention protocol. A directory move alone is not an assumed atomic table transaction on an object store.
The cache lab demonstrates a narrow reuse effect when repeatedly consulting a small synthetic working set. Reset, set both C=8 and s=2, predict an eight-address period with eight hits in sixteen initial requests, then Play or Step. Reset and re-enter both C=4 and s=2, predict no hits as the same period exceeds capacity, then inspect. It starts empty before the initial sixteen requests and caps at 4,096. The addresses are not partitions or manifest entries from a real table, so the lab cannot choose partition keys or estimate listing latency.
Work it through
Separate partition exclusion from within-day filtering
A dataset holds 30 days at 80 GB per day, evenly distributed. A query selects one full UTC day and one tenant whose rows are scattered throughout that day. Only the day partition can be excluded from metadata; use decimal GB.
Total logical dataset payload is 30 × 80 = 2,400 GB. Sound day pruning leaves one 80 GB partition, excluding 2,320 GB at that level.
The tenant predicate still requires work within that partition. A small tenant result does not imply proportional file skipping when its rows are scattered and summaries cannot reject files.
If the selected day has 160 equal-sized files, their average payload is 80/160 = 0.5 GB. A different clustering layout could improve tenant pruning, but its benefit must be measured along with rewrite cost and other queries.
The justified partition-level reduction is from 2,400 GB to 80 GB. Further reductions require actual file statistics, layout, and reader behavior rather than the tenant's output fraction alone.
The living notebook
Explore the model
Interactive lab · cache
Metadata reuse is not partition pruning
Reset, set both C=8 and s=2, predict eight hits among the initial sixteen requests, then Play or Step. Reset and re-enter C=4 and s=2 to compare the same eight-address cycle with too little capacity. The toy LRU stream caps at 4,096 requests and does not model partition transforms, manifests, or object-store listing latency.
- Hits / requests
- 0 / 16
- Hit rate
- 0%
- Address-stream period
- 16 addresses
A fully associative LRU cache starts empty and requests address (i·s) mod 16. Hits move an address to the newest position; misses evict the oldest when full. Playback starts with 16 requests and adds two per second, capped at 4096 explicitly simulated requests. This toy stream is not a processor-cache benchmark. 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 forCandidate-file discovery, metadata reuse, and physical data exclusion are related costs with different mechanisms.
Pause & reason
Check your understanding
Your turn
Try it yourself
Twelve equal monthly partitions each hold 60 GB. A query covers the final day of one month and first day of the next. With only month-level pruning, estimate candidate payload and explain why two days do not imply two-sixtieths of the bytes are read.
Take a moment to make a prediction or work it out on paper. Open a hint when you need one.
Give me a hint
First count touched month partitions; finer filtering needs additional evidence.
Compare with the solution
Two month partitions remain, totaling 120 GB of candidate logical payload out of 720 GB. The two-day predicate still needs residual filtering and might gain finer pruning from valid statistics or clustering. Month partition metadata alone cannot prove which physical pages inside those months can be skipped.
Keep the idea
Take it with you
- Partition pruning relies on a declared transform and a sound conservative predicate translation.
- File count, skew, and maintenance costs constrain how finely to partition.
- Partition exclusion and within-partition clustering provide distinct levels of skipping.
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.