Is there an existing issue for performance?
Environment
- Version or commit-id:
7821d21c72
- Branch:
optimize_filter_0711
- OS: Linux
- Scope: partition-state/workspace reads and ranges block-filter compilation
Details of Performance
Three confirmed paths preserve correctness but lose available early filtering and can scan substantially more in-memory rows, blocks, or object metadata than necessary.
-
Partition-state OR/disjunct filters
BasePKFilter.Disjuncts makes NewMemPKFilter invalid because the partition-state primary-key iterator accepts only one atomic predicate.
- Reads therefore fall back to
NewRowsIter and scan all visible in-memory rows even when every OR branch is individually primary-key-filterable.
-
Large PREFIX_IN in workspace reads
MemPKFilter.FilterVector intentionally returns without filtering when PREFIX_IN contains more than four prefixes.
- This avoids repeated linear matching, but turns a selective prefix set into a full workspace scan.
-
All-or-nothing ranges compilation
readutil.CompileFilterExprs marks the entire filter list as non-compilable when any one expression lacks a fast compiler implementation.
- The supported predicates then also lose object/block-level fast filtering, causing avoidable metadata loads and block scans.
These are performance gaps, not correctness bugs: residual SQL filters still produce correct query results.
Expected Behavior
- OR/disjunct primary-key predicates should use a safe union-capable partition-state iterator, or an equivalent bounded batch filter, whenever all branches are supported.
- Large
PREFIX_IN sets should use a scalable representation (for example, sorted prefixes with binary search/trie/range pruning) instead of disabling filtering.
- Ranges compilation should retain all independently compilable fast filters and route only unsupported predicates through the slow evaluator.
Steps to Reproduce
- Create a table with a primary key and leave selective rows in the transaction workspace/partition state.
- Execute a predicate that produces
BasePKFilter.Disjuncts, such as pk = 1 OR pk = 1000000; observe that the partition-state path cannot use the primary-key iterator.
- Execute
PREFIX_IN with more than four prefixes against workspace rows; observe that MemPKFilter.FilterVector skips early filtering.
- Construct a
BlockFilterList containing both a compiler-supported predicate and one zonemappable but unsupported predicate; observe CompileFilterExprs return canCompile=false for the whole list.
Proposed Direction and Acceptance Criteria
- Extend the partition-state iterator contract to represent OR safely; do not pass an unsupported synthetic op into existing single-range iterators.
- Add scalable
PREFIX_IN filtering with bounded memory and explicit tests for 0, 1, 4, 5, and large prefix counts.
- Split ranges filters into fast-compilable and slow-evaluated subsets while preserving AND semantics and fail-open behavior on compiler/filter errors.
- Add observability/tests for partition-state rows scanned, blocks selected, metadata/object loads, and fast-vs-slow compilation ratio.
- Verify correctness for NULLs, empty lists, overlapping prefixes, mixed OR branches, malformed filter state, and cancellation/error paths.
Additional information
This issue is the follow-up to the composite-key block-filter work in #21740. The current implementation deliberately keeps the three paths conservative to avoid false negatives; the goal is to remove the performance fallback without weakening that safety property.
Is there an existing issue for performance?
Environment
7821d21c72optimize_filter_0711Details of Performance
Three confirmed paths preserve correctness but lose available early filtering and can scan substantially more in-memory rows, blocks, or object metadata than necessary.
Partition-state OR/disjunct filters
BasePKFilter.DisjunctsmakesNewMemPKFilterinvalid because the partition-state primary-key iterator accepts only one atomic predicate.NewRowsIterand scan all visible in-memory rows even when every OR branch is individually primary-key-filterable.Large
PREFIX_INin workspace readsMemPKFilter.FilterVectorintentionally returns without filtering whenPREFIX_INcontains more than four prefixes.All-or-nothing ranges compilation
readutil.CompileFilterExprsmarks the entire filter list as non-compilable when any one expression lacks a fast compiler implementation.These are performance gaps, not correctness bugs: residual SQL filters still produce correct query results.
Expected Behavior
PREFIX_INsets should use a scalable representation (for example, sorted prefixes with binary search/trie/range pruning) instead of disabling filtering.Steps to Reproduce
BasePKFilter.Disjuncts, such aspk = 1 OR pk = 1000000; observe that the partition-state path cannot use the primary-key iterator.PREFIX_INwith more than four prefixes against workspace rows; observe thatMemPKFilter.FilterVectorskips early filtering.BlockFilterListcontaining both a compiler-supported predicate and one zonemappable but unsupported predicate; observeCompileFilterExprsreturncanCompile=falsefor the whole list.Proposed Direction and Acceptance Criteria
PREFIX_INfiltering with bounded memory and explicit tests for 0, 1, 4, 5, and large prefix counts.Additional information
This issue is the follow-up to the composite-key block-filter work in #21740. The current implementation deliberately keeps the three paths conservative to avoid false negatives; the goal is to remove the performance fallback without weakening that safety property.