diff --git a/tsdb/querier.go b/tsdb/querier.go index 8bcd451f3..9baf3f242 100644 --- a/tsdb/querier.go +++ b/tsdb/querier.go @@ -361,6 +361,22 @@ func postingsForMatcher(ix IndexReader, m *labels.Matcher) (index.Postings, erro // inversePostingsForMatcher returns the postings for the series with the label name set but not matching the matcher. func inversePostingsForMatcher(ix IndexReader, m *labels.Matcher) (index.Postings, error) { + // Fast-path for MatchNotRegexp matching. + // Inverse of a MatchNotRegexp is MatchRegexp (double negation). + // Fast-path for set matching. + if m.Type == labels.MatchNotRegexp { + setMatches := findSetMatches(m.GetRegexString()) + if len(setMatches) > 0 { + return ix.Postings(m.Name, setMatches...) + } + } + + // Fast-path for MatchNotEqual matching. + // Inverse of a MatchNotEqual is MatchEqual (double negation). + if m.Type == labels.MatchNotEqual { + return ix.Postings(m.Name, m.Value) + } + vals, err := ix.LabelValues(m.Name) if err != nil { return nil, err @@ -371,14 +387,6 @@ func inversePostingsForMatcher(ix IndexReader, m *labels.Matcher) (index.Posting if m.Type == labels.MatchEqual && m.Value == "" { res = vals } else { - // Inverse of a MatchNotRegexp is MatchRegexp (double negation). - // Fast-path for set matching. - if m.Type == labels.MatchNotRegexp { - setMatches := findSetMatches(m.GetRegexString()) - if len(setMatches) > 0 { - return ix.Postings(m.Name, setMatches...) - } - } for _, val := range vals { if !m.Matches(val) { res = append(res, val) diff --git a/tsdb/querier_bench_test.go b/tsdb/querier_bench_test.go index 6e5243ef1..19619e35b 100644 --- a/tsdb/querier_bench_test.go +++ b/tsdb/querier_bench_test.go @@ -125,6 +125,7 @@ func benchmarkPostingsForMatchers(b *testing.B, ir IndexReader) { {`n="X",j="foo"`, []*labels.Matcher{nX, jFoo}}, {`j="foo",n="1"`, []*labels.Matcher{jFoo, n1}}, {`n="1",j!="foo"`, []*labels.Matcher{n1, jNotFoo}}, + {`n="1",i!="2"`, []*labels.Matcher{n1, iNot2}}, {`n="X",j!="foo"`, []*labels.Matcher{nX, jNotFoo}}, {`i=~"1[0-9]",j=~"foo|bar"`, []*labels.Matcher{iCharSet, jFooBar}}, {`j=~"foo|bar"`, []*labels.Matcher{jFooBar}},