Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

colexec: add support for DISTINCT ordered aggregation #53145

Merged
merged 2 commits into from
Aug 21, 2020

Conversation

yuzefovich
Copy link
Member

rowexec: speed up DISTINCT aggregation a bit

Previously, whenever we needed to clear seen map (which tracks the
tuples we have already seen for the aggregation group), we would create
a new map. However, it turns out that it is actually faster (according
to micro-benchmarks) to delete all entries from the old map instead
which is what this commit does.

Release note: None

colexec: add support for DISTINCT ordered aggregation

This commit adds the support for DISTINCT ordered aggregation by
reusing the same code (with minor modification to reset seen maps when
the new group is encountered) as we have for hash aggregation. Quick
benchmarks show about 6-7x improvement when comparing against a wrapped
row-by-row processor.

Closes: #39242.

Release note (sql change): Vectorized execution now natively supports
ordered aggregation with DISTINCT clause.

@cockroach-teamcity
Copy link
Member

This change is Reviewable

@yuzefovich
Copy link
Member Author

yuzefovich commented Aug 20, 2020

Wrapped processor performance on master:

BenchmarkDistinctAggregation/ordered/COUNT/groupSize=2/distinctProb=0.10/nulls=false-16         	      31	  33726789 ns/op	  15.55 MB/s
BenchmarkDistinctAggregation/ordered/COUNT/groupSize=512/distinctProb=0.01/nulls=false-16       	      36	  33585869 ns/op	  15.61 MB/s
BenchmarkDistinctAggregation/ordered/COUNT/groupSize=512/distinctProb=0.10/nulls=false-16       	      34	  33619913 ns/op	  15.59 MB/s
BenchmarkDistinctAggregation/ordered/COUNT/groupSize=1024/distinctProb=0.01/nulls=false-16      	      34	  33414499 ns/op	  15.69 MB/s
BenchmarkDistinctAggregation/ordered/COUNT/groupSize=1024/distinctProb=0.10/nulls=false-16      	      36	  33891886 ns/op	  15.47 MB/s

Wrapped processor performance with the first commit:

BenchmarkDistinctAggregation/ordered/COUNT/groupSize=2/distinctProb=0.10/nulls=false-16         	      40	  28836370 ns/op	  18.18 MB/s
BenchmarkDistinctAggregation/ordered/COUNT/groupSize=512/distinctProb=0.01/nulls=false-16       	      42	  28592696 ns/op	  18.34 MB/s
BenchmarkDistinctAggregation/ordered/COUNT/groupSize=512/distinctProb=0.10/nulls=false-16       	      43	  28456743 ns/op	  18.42 MB/s
BenchmarkDistinctAggregation/ordered/COUNT/groupSize=1024/distinctProb=0.01/nulls=false-16      	      42	  28223842 ns/op	  18.58 MB/s
BenchmarkDistinctAggregation/ordered/COUNT/groupSize=1024/distinctProb=0.10/nulls=false-16      	      40	  28304850 ns/op	  18.52 MB/s

Vectorized operator performance:

BenchmarkDistinctAggregation/ordered/COUNT/groupSize=2/distinctProb=0.10/nulls=false-16         	     240	   4965222 ns/op	 105.59 MB/s
BenchmarkDistinctAggregation/ordered/COUNT/groupSize=512/distinctProb=0.01/nulls=false-16       	     242	   4917969 ns/op	 106.61 MB/s
BenchmarkDistinctAggregation/ordered/COUNT/groupSize=512/distinctProb=0.10/nulls=false-16       	     242	   4922210 ns/op	 106.51 MB/s
BenchmarkDistinctAggregation/ordered/COUNT/groupSize=1024/distinctProb=0.01/nulls=false-16      	     244	   4929168 ns/op	 106.36 MB/s
BenchmarkDistinctAggregation/ordered/COUNT/groupSize=1024/distinctProb=0.10/nulls=false-16      	     242	   4970665 ns/op	 105.48 MB/s

(Note that I did update the benchmark harness to properly recreate the operator chain - with TestNewColOperator call - for a fair comparison.)

@yuzefovich yuzefovich force-pushed the distinct-ord-agg branch 3 times, most recently from 7bd4098 to 0dbe896 Compare August 20, 2020 21:01
@yuzefovich yuzefovich requested review from asubiotto and a team August 20, 2020 21:01
Copy link
Contributor

@asubiotto asubiotto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:lgtm: could you create an issue about using the vectorized hash table for distinct aggregation?

Reviewed 1 of 1 files at r1, 8 of 8 files at r2.
Reviewable status: :shipit: complete! 1 of 0 LGTMs obtained (waiting on @yuzefovich)


pkg/sql/colexec/aggregate_funcs.go, line 371 at r2 (raw file):

	// seen is a slice of maps used to handle distinct aggregation. A
	// corresponding entry in the slice is nil if the function doesn't have a
	// DISTINCT clause. The slice itself will be nil whenever no aggregate

nit: do you mean the map instead of the slice?


pkg/sql/colexec/aggregators_util.go, line 41 at r2 (raw file):

	// tuples that pass the criteria - like DISTINCT and/or FILTER will be
	// aggregated).
	performAggregation(ctx context.Context, vecs []coldata.Vec, inputLen int, sel []int, bucket *aggBucket, groups []bool)

Add reference to groups in comment.

@yuzefovich yuzefovich force-pushed the distinct-ord-agg branch 2 times, most recently from 49b87e6 to c9c0f3a Compare August 21, 2020 16:02
Copy link
Member Author

@yuzefovich yuzefovich left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is likely that the vectorized hash table will still show worse performance, and I intend to prototype it today, so I don't think an issue is necessary.

TFTR!

bors r+

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (and 1 stale) (waiting on @asubiotto)


pkg/sql/colexec/aggregate_funcs.go, line 371 at r2 (raw file):

Previously, asubiotto (Alfonso Subiotto Marqués) wrote…

nit: do you mean the map instead of the slice?

No, I did mean the "slice of maps" will be nil.


pkg/sql/colexec/aggregators_util.go, line 41 at r2 (raw file):

Previously, asubiotto (Alfonso Subiotto Marqués) wrote…

Add reference to groups in comment.

Done.

@yuzefovich
Copy link
Member Author

Huh, merge conflict.

bors r-

@craig
Copy link
Contributor

craig bot commented Aug 21, 2020

Canceled.

Previously, whenever we needed to clear `seen` map (which tracks the
tuples we have already seen for the aggregation group), we would create
a new map. However, it turns out that it is actually faster (according
to micro-benchmarks) to delete all entries from the old map instead
which is what this commit does.

Release note: None
This commit adds the support for DISTINCT ordered aggregation by
reusing the same code (with minor modification to reset `seen` maps when
the new group is encountered) as we have for hash aggregation. Quick
benchmarks show about 6-7x improvement when comparing against a wrapped
row-by-row processor.

Release note (sql change): Vectorized execution now natively supports
ordered aggregation with DISTINCT clause.
@yuzefovich
Copy link
Member Author

As I expected, the vectorized hash table is worse (especially on small group sizes it's just terrible) because our hash table is pretty heavy-weight since it has several constant allocations of coldata.BatchSize() in size, so I removed the TODO.

bors r+

@asubiotto
Copy link
Contributor

The fact we do distinct tuple-at-a-time makes me think there are definitely some performance optimizations we could take advantage of. Is it a question of growing those allocations dynamically or something else? I guess the issue is more so that you can record your thoughts if you can think of anything for the future.

@yuzefovich
Copy link
Member Author

yuzefovich commented Aug 21, 2020

It's a matter of hash table allocating many slices (I think 9 of them in this use case) of coldata.BatchSize() in size regardless of the number of elements that will be added because the hash table has built-in assumptions that it could be probed with batches up to coldata.BatchSize() and currently doesn't reallocate those slices dynamically. Maybe those assumptions should be challenged, and the slices could grow dynamically. I don't have much thoughts to put into an issue other than that performance I saw was 100x worse in some cases.

@knz
Copy link
Contributor

knz commented Aug 21, 2020

The following error was encountered on the bors run: https://teamcity.cockroachdb.com/buildConfiguration/Cockroach_UnitTests/2208105?

=== RUN   TestExternalHashJoinerFallbackToSortMergeJoin
ERROR: a panic has occurred!
Details cannot be printed yet because we are still unwinding.
Hopefully the test harness prints the panic below, otherwise check the test logs.
test logs left over in: /go/src/github.com/cockroachdb/cockroach/artifacts/logTestExternalHashJoinerFallbackToSortMergeJoin690293980
--- FAIL: TestExternalHashJoinerFallbackToSortMergeJoin (0.00s)
test_log_scope.go:154: test logs captured to: /go/src/github.com/cockroachdb/cockroach/artifacts/logTestExternalHashJoinerFallbackToSortMergeJoin690293980
test_log_scope.go:63: use -show-logs to present logs inline
panic: runtime error: slice bounds out of range [:1588] with capacity 1024 [recovered]
  panic: runtime error: slice bounds out of range [:1588] with capacity 1024 [recovered]
  panic: runtime error: slice bounds out of range [:1588] with capacity 1024
goroutine 142 [running]:
testing.tRunner.func1(0xc000122900)
  /usr/local/go/src/testing/testing.go:874 +0x3a3
panic(0x338a9a0, 0xc0044b03a0)
  /usr/local/go/src/runtime/panic.go:679 +0x1b2
github.com/cockroachdb/cockroach/pkg/util/leaktest.AfterTest.func2()
  /go/src/github.com/cockroachdb/cockroach/pkg/util/leaktest/leaktest.go:103 +0x22f
panic(0x338a9a0, 0xc0044b03a0)
  /usr/local/go/src/runtime/panic.go:679 +0x1b2
github.com/cockroachdb/cockroach/pkg/sql/colexec.(*hashJoiner).exec(0xc000453500, 0x40c1e00, 0xc000052130, 0x0, 0xc00005d100)
  /go/src/github.com/cockroachdb/cockroach/pkg/sql/colexec/hashjoiner.go:447 +0x881
github.com/cockroachdb/cockroach/pkg/sql/colexec.(*hashJoiner).Next(0xc000453500, 0x40c1e00, 0xc000052130, 0x0, 0x0)
  /go/src/github.com/cockroachdb/cockroach/pkg/sql/colexec/hashjoiner.go:279 +0xf1
github.com/cockroachdb/cockroach/pkg/sql/colexec.(*externalHashJoiner).Next(0xc0002d38c0, 0x40c1e00, 0xc000052130, 0xd, 0x0)
  /go/src/github.com/cockroachdb/cockroach/pkg/sql/colexec/external_hash_joiner.go:649 +0xdb6
github.com/cockroachdb/cockroach/pkg/sql/colexec.(*diskSpillerBase).Next(0xc001d3a980, 0x40c1e00, 0xc000052130, 0x0, 0x0)
  /go/src/github.com/cockroachdb/cockroach/pkg/sql/colexec/disk_spiller.go:212 +0x181
github.com/cockroachdb/cockroach/pkg/sql/colexec.TestExternalHashJoinerFallbackToSortMergeJoin(0xc000122900)
  /go/src/github.com/cockroachdb/cockroach/pkg/sql/colexec/external_hash_joiner_test.go:181 +0xa14

@yuzefovich
Copy link
Member Author

I'll take a look, but I think it is more likely that #53169 is the culprit and not this PR.

@knz
Copy link
Contributor

knz commented Aug 21, 2020

that's bad isn't it? This means that all current and future bors runs will have a chance to fail?

@yuzefovich
Copy link
Member Author

It'll be random because we randomize coldata.BatchSize(). If this is the only failing test, then they will fail with roughly 0.2 probability.

@knz
Copy link
Contributor

knz commented Aug 21, 2020

thanks for checking

@craig
Copy link
Contributor

craig bot commented Aug 21, 2020

Build failed (retrying...):

@craig
Copy link
Contributor

craig bot commented Aug 21, 2020

Build failed (retrying...):

@craig
Copy link
Contributor

craig bot commented Aug 21, 2020

Build succeeded:

@craig craig bot merged commit cab0b31 into cockroachdb:master Aug 21, 2020
@yuzefovich yuzefovich deleted the distinct-ord-agg branch August 21, 2020 21:23
@yuzefovich
Copy link
Member Author

I prototyped handling DISTINCT aggregation using more dynamic hash table (on top of #53226), and it turned out that the performance of distinct hash aggregation is better with current encoding strategy, but for the ordered aggregator it is better with the vectorized hash table. I'll open up an issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

exec: add distinct aggregation support
4 participants