app/vmselect/promql: remove empty time series after applying filters like q > 0

This should reduce CPU and RAM usage for queries over high number of time series.
This commit is contained in:
Aliaksandr Valialkin 2019-07-12 19:56:23 +03:00
parent 3bc9d3a14c
commit 092c9b39a8
2 changed files with 12 additions and 4 deletions

View file

@ -260,6 +260,9 @@ func newBinaryOpFunc(bf func(left, right float64, isBool bool) float64) binaryOp
dstValues[j] = bf(a, b, isBool) dstValues[j] = bf(a, b, isBool)
} }
} }
// Optimization: remove time series containing only NaNs.
// This is quite common after applying filters like `q > 0`.
dst = removeNaNs(dst)
return dst, nil return dst, nil
} }
} }

View file

@ -131,18 +131,23 @@ func timeseriesToResult(tss []*timeseries, maySort bool) ([]netstorage.Result, e
func removeNaNs(tss []*timeseries) []*timeseries { func removeNaNs(tss []*timeseries) []*timeseries {
rvs := tss[:0] rvs := tss[:0]
for _, ts := range tss { for _, ts := range tss {
nans := 0 allNans := true
for _, v := range ts.Values { for _, v := range ts.Values {
if math.IsNaN(v) { if !math.IsNaN(v) {
nans++ allNans = false
break
} }
} }
if nans == len(ts.Values) { if allNans {
// Skip timeseries with all NaNs. // Skip timeseries with all NaNs.
continue continue
} }
rvs = append(rvs, ts) rvs = append(rvs, ts)
} }
for i := len(rvs); i < len(tss); i++ {
// Zero unused time series, so GC could reclaim them.
tss[i] = nil
}
return rvs return rvs
} }