2.6 KiB
2.6 KiB
078 — Metric-comparison filters scan every metric's buckets on every query
Summary
Same underlying issue as ticket 077 (iterators should narrow the key
range as far as possible, and take a range as a parameter), applied to
metrics: a metric-comparison filter (e.g. latency_ms[value]<200 in
the filter bar) rebuilds its matching-sequence set from scratch on
every single query by scanning all buckets for all metrics, then
discarding everything that doesn't match the requested metric name —
instead of seeking directly to that metric's key range.
Where
EngineSnapshot::bucket_values(src/engine/snapshot/metrics.rs:295-312) rangesIndexKey::MetricBucketSplit..IndexKey::End— every bucket for every declared metric — and filters byname == metric_nameinside thefilter_mapclosure.IndexKey::Bucket { metric_name, labels }(src/engine/index_key.rs:23-26) derivesOrdonmetric_namefirst, so this is seekable: a lower bound ofIndexKey::Bucket { metric_name: metric_name.into(), labels: BTreeMap::new() }and an upper bound one metric name past it would narrow the range to just that metric's buckets.- The compare-filter compiler,
compile_metric_comparison(src/engine/snapshot/filter.rs:83-104), callsself.bucket_values(metric, None)and builds a freshHashSet<u64>of matching sequences on every call — this runs once per filter compile, and filters are compiled fresh per query (compile_filter_query, called fromsrc/engine/snapshot/query.rs:46), so a dashboard or search bar polling with a metric-comparison filter re-scans all bucket values every poll interval. Unlike the log sort-helper indexes (src/engine/snapshot/sort.rs), there is no incremental cache here keyed by(metric, param, op, value).
Scope
- Narrow
bucket_valuesto accept/derive a key range for the requestedmetric_nameinstead of rangingMetricBucketSplit..Endand filtering by name in the closure. This alone removes the "every other metric's buckets" part of the scan regardless of caching. - Separately (bigger win, more invasive — may warrant its own
follow-up ticket): consider whether metric-comparison results can be
incrementally maintained similarly to
sort_helper_indexes(src/engine/snapshot/sort.rs) rather than recomputed per query, if profiling shows compare-filtered dashboard polling is a hot path. Keep this ticket scoped to the range-narrowing fix; note the caching idea here so it isn't lost, but split it out if it turns out to need design work (cache invalidation on new bucket values, per unique filter expression).
Depends on
None. Same principle as ticket 077.