From e53f9e553d2b7cab73b03fa1c334dbaeaea11533 Mon Sep 17 00:00:00 2001 From: Aliaksandr Valialkin Date: Tue, 5 Nov 2019 12:57:45 +0200 Subject: [PATCH] lib/storage: try potentially faster tag filters at first, then apply slower tag filters The fastest tag filters are non-negative non-regexp, since they are the most specific. The slowest tag filters are negative regexp, since they require scanning all the entries for the given label. --- lib/storage/index_db.go | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/lib/storage/index_db.go b/lib/storage/index_db.go index 3e270fd37c..215eff241c 100644 --- a/lib/storage/index_db.go +++ b/lib/storage/index_db.go @@ -1544,7 +1544,22 @@ func (is *indexSearch) searchMetricIDs(tfss []*TagFilters, tr TimeRange, maxMetr func (is *indexSearch) updateMetricIDsForTagFilters(metricIDs *uint64set.Set, tfs *TagFilters, tr TimeRange, maxMetrics int) error { // Sort tag filters for faster ts.Seek below. - sort.Slice(tfs.tfs, func(i, j int) bool { return bytes.Compare(tfs.tfs[i].prefix, tfs.tfs[j].prefix) < 0 }) + sort.Slice(tfs.tfs, func(i, j int) bool { + // Move regexp and negative filters to the end, since they require scanning + // all the entries for the given label. + a := &tfs.tfs[i] + b := &tfs.tfs[j] + if a.isRegexp != b.isRegexp { + return !a.isRegexp + } + if a.isNegative != b.isNegative { + return !a.isNegative + } + if len(a.orSuffixes) != len(b.orSuffixes) { + return len(a.orSuffixes) < len(b.orSuffixes) + } + return bytes.Compare(a.prefix, b.prefix) < 0 + }) minTf, minMetricIDs, err := is.getTagFilterWithMinMetricIDsCountOptimized(tfs, tr, maxMetrics) if err != nil {