<!-- llms-explorer concept facts · https://llms-explorer.com/tree/interval-evaluation-trees-and-parameterized-plan-caching/ · pack 2026-10-23 · ~1804 tokens -->

# Interval evaluation trees and parameterized plan caching

> Source-anchored research for Interval evaluation trees and parameterized plan caching. Run status: COMPLETED.

Parent: [SORT_MERGE and $in sort expansion](https://llms-explorer.com/tree/sort-merge-and-in-sort-expansion/) · 5 facets · 16 facts · page: https://llms-explorer.com/tree/interval-evaluation-trees-and-parameterized-plan-caching/

## Structure and components

- Without an eligible sort, this SBE $in-length key component is omitted. With a sort, changing eligible $in values while preserving their unique count can retain the key; changing a below-cap count changes that component. Other cache-key properties must still match. (high confidence) — [source](https://github.com/mongodb/mongo/blob/35647d07bc4bc11966c90fe7100eb1db0b0ac1d9/src/mongo/db/query/canonical_query_encoder.cpp)

## How it works

- At revision 35647d07bc4bc11966c90fe7100eb1db0b0ac1d9, the SBE encoder includes the number of unique $in equalities when the expression is parameterized and the query has a sort. It encodes min(maxScansToExplode + 1, equalityCount), separating potentially different branch counts while allowing larger non-explodable lists to share that discriminator. This extra count is omitted without a sort. (high confidence) — [source](https://github.com/mongodb/mongo/blob/35647d07bc4bc11966c90fe7100eb1db0b0ac1d9/src/mongo/db/query/canonical_query_encoder.cpp)
- Structural compatibility does not guarantee that one cached access path remains efficient for all parameter values. The Sydney researchers vary predicate selectivity to study plan choices, and Percona describes uneven indexed-value distributions as a cause of unstable cached-plan performance. (medium confidence) — [source](https://15799.courses.cs.cmu.edu/spring2025/papers/23-mongodb/tao-adc2024.pdf)
- SERVER-97685, last updated December 6, 2024, says IETs were then unused because the SBE plan cache was disabled and flags large-IET construction/cloning problems for a future re-enable. This scopes the architecture description: source-code support does not establish that a given deployed version enables that path. (low confidence) (verified as of 2024-12-06) — [source](https://jira.mongodb.org/browse/SERVER-97685)

## Problems, failure modes and limitations

- Validate parameterized cache reuse with ordinary query executions and $planCacheStats inspection. The MongoDB regression test executes queries to create/activate entries and checks results and cache entries; explain() alone cannot prove reuse because the manual says it ignores existing entries and creates no new entry. (high confidence) — [source](https://github.com/mongodb/mongo/blob/35647d07bc4bc11966c90fe7100eb1db0b0ac1d9/jstests/core/query/plan_cache/in_expression_plan_cache.js)
- SERVER-66459 documented a correctness failure: sort expansion discarded IETs, so downstream code embedded fixed KeyString bounds and cached reuse with new literals could omit matching documents. SERVER-67576 describes initially excluding these plans from caching before restoring safe support. These are historical defects, not evidence that every current sorted $in query is wrong. (high confidence) — [source](https://jira.mongodb.org/browse/SERVER-66459)

## Comparisons and alternatives

- On the SBE plan-cache path, eligible filter constants receive parameter IDs and runtime slots. IETs reconstruct index bounds from the incoming parameter-to-expression mapping instead of freezing the first query's literal bounds. (high confidence) — [source](https://github.com/mongodb/mongo/blob/master/src/mongo/db/query/plan_cache/README.md)
- SERVER-90415 records a change for 8.0 and master release builds to use the classic plan cache instead of the SBE cache, while retaining the SBE cache under the SBE-full feature flag. Its fix versions include 8.0.0-rc7 and 8.1.0-rc0. Therefore SBE execution alone does not establish that IET-based SBE cache reuse occurred. (low confidence) (verified as of 2026-09-21) — [source](https://jira.mongodb.org/browse/SERVER-90415)
- Inspect actual cache entries with getPlanCache().list() or $planCacheStats when investigating reuse across different $in values or cardinalities. Inspect planCacheKey and cache state alongside the query, rather than assuming parameterization from similar query text. (high confidence) — [source](https://github.com/mongodb/mongo/blob/master/src/mongo/db/query/plan_cache/README.md)

## Facts and statements

- At revision 35647d07bc4bc11966c90fe7100eb1db0b0ac1d9, isOilExplodable requires a nonempty union of point intervals. If an IET is present, it accepts only ConstNode or an EvalNode for EQ/MATCH_IN; union/intersection IETs can change interval counts after rebinding and are rejected. This protects the cached sort-merge branch count. (high confidence) — [source](https://github.com/mongodb/mongo/blob/35647d07bc4bc11966c90fe7100eb1db0b0ac1d9/src/mongo/db/query/planner_analysis.cpp)
- In the inspected planner revision, exploded scans wrap appropriate source IETs in ExplodeNode with an explosion identity and interval position. Unexploded suffix IETs are copied into each child. This associates a reused child scan with its intended regenerated point interval. (low confidence) — [source](https://github.com/mongodb/mongo/blob/35647d07bc4bc11966c90fe7100eb1db0b0ac1d9/src/mongo/db/query/planner_analysis.cpp)
- Classic and SBE plan-cache reuse have different structural constraints: classic stores index-assignment information and reconstructs bounds and the plan for the incoming query, whereas the SBE cache stores a reusable execution tree. The $in regression test explains that classic applies explode-for-sort after cache retrieval. (high confidence) — [source](https://github.com/mongodb/mongo/blob/master/src/mongo/db/query/plan_cache/README.md)
- The 2024 First Past the Post paper explicitly disables query-plan caching in its experiments. Its optimizer results provide selectivity context, not experimental validation of IET correctness or parameterized cache-hit behavior. (low confidence) — [source](https://15799.courses.cs.cmu.edu/spring2025/papers/23-mongodb/tao-adc2024.pdf)
- Plan caching avoids repeated planning for compatible query shapes. Literal changes can reuse a plan, but eligibility and cache-key discrimination still matter; sharing a broad query shape does not guarantee the same cache entry. (high confidence) — [source](https://github.com/mongodb/mongo/blob/master/src/mongo/db/query/plan_cache/README.md)
- The documented SBE cache stores an executable PlanStage tree, clones it for each query, and binds eligible filter constants through RuntimeEnvironment slots. The classic cache instead stores index-selection information used to reconstruct a plan and bounds. (low confidence) — [source](https://github.com/mongodb/mongo/blob/master/src/mongo/db/query/plan_cache/README.md)
- SERVER-67576 records the caching improvement as fixed in 7.0.0-rc0 and resolved on March 22, 2023. Its description proposes runtime branch creation as one possible approach; that proposal alone does not establish the implemented strategy. (low confidence) (verified as of 2023-10-29) — [source](https://jira.mongodb.org/browse/SERVER-67576)
