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

sql/kv: avoid expensive heap allocations with inverted joins #53181

Conversation

nvanbenschoten
Copy link
Member

This PR contains three optimizations that reduce heap allocations by
inverted join operations. These were found by profiling the following
geospatial query:

SELECT Count(census.blkid), Count(subways.name)
FROM nyc_census_blocks AS census
JOIN nyc_subway_stations AS subways
ON ST_Intersects(subways.geom, census.geom);

Combined, these three commits speed up the query by a little over 3%.

name                                old ms    new ms    delta
Test/postgis_geometry_tutorial/nyc  139 ±12%  135 ±11%  -3.04%  (p=0.000 n=241+243)

sql/rowexec: avoid heap allocations in batchedInvertedExprEvaluator

This commit restructures the slice manipulation performed in
(*batchedInvertedExprEvaluator).init to avoid heap allocations. Before
the change, this method used to contain the first and fifth most
expensive memory allocations by total allocation size (alloc_space)
in a geospatial query of interest:

----------------------------------------------------------+-------------
                                         3994.06MB   100% |   github.com/cockroachdb/cockroach/pkg/sql/rowexec.(*invertedJoiner).readInput /go/src/github.com/cockroachdb/cockroach/pkg/sql/rowexec/inverted_joiner.go:418
 3994.06MB 10.70% 10.70%  3994.06MB 10.70%                | github.com/cockroachdb/cockroach/pkg/sql/rowexec.(*batchedInvertedExprEvaluator).init /go/src/github.com/cockroachdb/cockroach/pkg/sql/rowexec/inverted_expr_evaluator.go:366
----------------------------------------------------------+-------------

----------------------------------------------------------+-------------
                                          954.07MB   100% |   github.com/cockroachdb/cockroach/pkg/sql/rowexec.(*invertedJoiner).readInput /go/src/github.com/cockroachdb/cockroach/pkg/sql/rowexec/inverted_joiner.go:418
  954.07MB  4.61% 41.71%   954.07MB  4.61%                | github.com/cockroachdb/cockroach/pkg/sql/rowexec.(*batchedInvertedExprEvaluator).init /go/src/github.com/cockroachdb/cockroach/pkg/sql/rowexec/inverted_expr_evaluator.go:409
----------------------------------------------------------+-------------

The largest offender here was the routingSpans slice, which made no
attempt to recycle memory. The other offender was the pendingSpans
slice. We made an attempt to recycle the memory in this slice, except
we truncated it from the front instead of the back, so we ended us
not actually recycling anything.

This commit addresses this in two ways. First, it updates the pendingSpans
slice to point into the routingSpans slice so the two can share memory.
pendingSpans becomes a mutable window into routingSpans, so it no
longer requires its own heap allocation. Next, the commit updates the
memory recycling to recycle routingSpans instead of pendingSpans.
Since we never truncate routingSpans from the front, the recycling
now works.

With these two changes, the two heap allocations, which used to account
for 15.31% of total allocated space combined drops to a single heap
allocation that accounts for only 2.43% of total allocated space on
the geospatial query.

----------------------------------------------------------+-------------
                                          182.62MB   100% |   github.com/cockroachdb/cockroach/pkg/sql/rowexec.(*invertedJoiner).readInput /go/src/github.com/cockroachdb/cockroach/pkg/sql/rowexec/inverted_joiner.go:418
  182.62MB  2.43% 58.36%   182.62MB  2.43%                | github.com/cockroachdb/cockroach/pkg/sql/rowexec.(*batchedInvertedExprEvaluator).init /go/src/github.com/cockroachdb/cockroach/pkg/sql/rowexec/inverted_expr_evaluator.go:366
----------------------------------------------------------+-------------

sql: properly copy span slices

This commit fixes two locations where we not optimally performing copies
from one slice to another.

In invertedJoiner.generateSpans, we were not pre-allocating the
destination slice and were using append instead of direct assignment,
which is measurably slower due to the extra writes to the slice header.

In getProtoSpans, we again were appending to a slice with zero length
and sufficient capacity instead of assigning to a slice with sufficient
length.

kv: check for expensive logging before VEventf in appendRefreshSpans

Before this change, we called VEventf directly with the refresh span
corresponding to each request in a batch. This caused each span object
to allocate while passing through an interface{}. This could be seen
in heap profiles, where it accounted for 1.89% of total allocated
memory (alloc_space) in a geospatial query of interest:

----------------------------------------------------------+-------------
                                          142.01MB   100% |   github.com/cockroachdb/cockroach/pkg/roachpb.(*BatchRequest).RefreshSpanIterate /go/src/github.com/cockroachdb/cockroach/pkg/roachpb/batch.go:407
  142.01MB  1.89% 68.71%   142.01MB  1.89%                | github.com/cockroachdb/cockroach/pkg/kv/kvclient/kvcoord.(*txnSpanRefresher).appendRefreshSpans.func1 /go/src/github.com/cockroachdb/cockroach/pkg/kv/kvclient/kvcoord/txn_interceptor_span_refresher.go:510
----------------------------------------------------------+-------------

This commit adds a guard around the VEventf to avoid the allocation.

@nvanbenschoten nvanbenschoten requested a review from a team as a code owner August 21, 2020 04:46
@cockroach-teamcity
Copy link
Member

This change is Reviewable

Copy link
Collaborator

@sumeerbhola sumeerbhola left a comment

Choose a reason for hiding this comment

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

This caused each span object to allocate while passing through an interface{}.

Is this an allocation of the interface instance or the roachpb.Span? Do you know why it needs to allocate on the heap -- the parameter doesn't seem like it should escape?

:lgtm:

Reviewed 1 of 1 files at r1, 2 of 2 files at r2.
Reviewable status: :shipit: complete! 1 of 0 LGTMs obtained (waiting on @nvanbenschoten and @sumeerbhola)


pkg/sql/rowexec/inverted_expr_evaluator.go, line 397 at r1 (raw file):

	pendingSpans := b.routingSpans[:1]
	// This loop does both the union of the routingSpans and fragments the
	// routingSpans.

nice!
Can you add the following to this comment
// The pendingSpans slice contains a subsequence of the routingSpans slice, that
// when passed to fragmentPendingSpans will be mutated by it.

This commit restructures the slice manipulation performed in
`(*batchedInvertedExprEvaluator).init` to avoid heap allocations. Before
the change, this method used to contain the first and fifth most
expensive memory allocations by total allocation size (`alloc_space`)
in a geospatial query of interest:
```
----------------------------------------------------------+-------------
                                         3994.06MB   100% |   github.com/cockroachdb/cockroach/pkg/sql/rowexec.(*invertedJoiner).readInput /go/src/github.com/cockroachdb/cockroach/pkg/sql/rowexec/inverted_joiner.go:418
 3994.06MB 10.70% 10.70%  3994.06MB 10.70%                | github.com/cockroachdb/cockroach/pkg/sql/rowexec.(*batchedInvertedExprEvaluator).init /go/src/github.com/cockroachdb/cockroach/pkg/sql/rowexec/inverted_expr_evaluator.go:366
----------------------------------------------------------+-------------

----------------------------------------------------------+-------------
                                          954.07MB   100% |   github.com/cockroachdb/cockroach/pkg/sql/rowexec.(*invertedJoiner).readInput /go/src/github.com/cockroachdb/cockroach/pkg/sql/rowexec/inverted_joiner.go:418
  954.07MB  4.61% 41.71%   954.07MB  4.61%                | github.com/cockroachdb/cockroach/pkg/sql/rowexec.(*batchedInvertedExprEvaluator).init /go/src/github.com/cockroachdb/cockroach/pkg/sql/rowexec/inverted_expr_evaluator.go:409
----------------------------------------------------------+-------------
```

The largest offender here was the `routingSpans` slice, which made no
attempt to recycle memory. The other offender was the `pendingSpans`
slice. We made an attempt to recycle the memory in this slice, except
we truncated it from the front instead of the back, so we ended us
not actually recycling anything.

This commit addresses this in two ways. First, it updates the `pendingSpans`
slice to point into the `routingSpans` slice so the two can share memory.
`pendingSpans` becomes a mutable window into `routingSpans`, so it no
longer requires its own heap allocation. Next, the commit updates the
memory recycling to recycle `routingSpans` instead of `pendingSpans`.
Since we never truncate `routingSpans` from the front, the recycling
now works.

With these two changes, the two heap allocations, which used to account
for **15.31%** of total allocated space combined drops to a single heap
allocation that accounts for only **2.43%** of total allocated space on
the geospatial query.

```
----------------------------------------------------------+-------------
                                          182.62MB   100% |   github.com/cockroachdb/cockroach/pkg/sql/rowexec.(*invertedJoiner).readInput /go/src/github.com/cockroachdb/cockroach/pkg/sql/rowexec/inverted_joiner.go:418
  182.62MB  2.43% 58.36%   182.62MB  2.43%                | github.com/cockroachdb/cockroach/pkg/sql/rowexec.(*batchedInvertedExprEvaluator).init /go/src/github.com/cockroachdb/cockroach/pkg/sql/rowexec/inverted_expr_evaluator.go:366
----------------------------------------------------------+-------------
```
This commit fixes two locations where we not optimally performing copies
from one slice to another.

In `invertedJoiner.generateSpans`, we were not pre-allocating the
destination slice and were using append instead of direct assignment,
which is measurably slower due to the extra writes to the slice header.

In `getProtoSpans`, we again were appending to a slice with zero length
and sufficient capacity instead of assigning to a slice with sufficient
length.
Before this change, we called VEventf directly with the refresh span
corresponding to each request in a batch. This caused each span object
to allocate while passing through an `interface{}`. This could be seen
in heap profiles, where it accounted for **1.89%** of total allocated
memory (`alloc_space`) in a geospatial query of interest:

```
----------------------------------------------------------+-------------
                                          142.01MB   100% |   github.com/cockroachdb/cockroach/pkg/roachpb.(*BatchRequest).RefreshSpanIterate /go/src/github.com/cockroachdb/cockroach/pkg/roachpb/batch.go:407
  142.01MB  1.89% 68.71%   142.01MB  1.89%                | github.com/cockroachdb/cockroach/pkg/kv/kvclient/kvcoord.(*txnSpanRefresher).appendRefreshSpans.func1 /go/src/github.com/cockroachdb/cockroach/pkg/kv/kvclient/kvcoord/txn_interceptor_span_refresher.go:510
----------------------------------------------------------+-------------
```

This commit adds a guard around the VEventf to avoid the allocation.
@nvanbenschoten nvanbenschoten force-pushed the nvanbenschoten/batchedInvertedExprEvaluator2 branch from 7f72036 to e69f860 Compare August 21, 2020 14:20
Copy link
Member Author

@nvanbenschoten nvanbenschoten left a comment

Choose a reason for hiding this comment

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

TFTR!

Is this an allocation of the interface instance or the roachpb.Span? Do you know why it needs to allocate on the heap -- the parameter doesn't seem like it should escape?

An allocation of the roachpb.Span. Passing a value through an interface almost always causes that value to escape to the heap. Escape analysis is usually pretty useless in these cases, except when the entire thing can be inlined away. We can confirm that it's the roachpb.Span itself that's escaping in the heap profile because the allocation has a size of 48 bytes:
Screen Shot 2020-08-21 at 10.08.06 AM.png

Also, we see the following in the debug compilation output:

txn_interceptor_span_refresher.go:565:23: span escapes to heap

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


pkg/sql/rowexec/inverted_expr_evaluator.go, line 397 at r1 (raw file):

Previously, sumeerbhola wrote…

nice!
Can you add the following to this comment
// The pendingSpans slice contains a subsequence of the routingSpans slice, that
// when passed to fragmentPendingSpans will be mutated by it.

Done.

Copy link
Collaborator

@sumeerbhola sumeerbhola left a comment

Choose a reason for hiding this comment

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

:lgtm:

Reviewed 1 of 3 files at r3, 2 of 2 files at r4, 1 of 1 files at r5.
Reviewable status: :shipit: complete! 1 of 0 LGTMs obtained (waiting on @sumeerbhola)

@nvanbenschoten
Copy link
Member Author

bors r+

@craig
Copy link
Contributor

craig bot commented Aug 21, 2020

Build failed (retrying...):

nvanbenschoten added a commit to nvanbenschoten/cockroach that referenced this pull request Aug 21, 2020
…oSpanExpr

This commit optimizes a few heap allocations in `GeoUnionKeySpansToSpanExpr` and
in `GeoRPKeyExprToSpanExpr` to avoid per-span/per-expression heap allocations.

Before this change, these heap allocations accounted for 27.52% of all heap
allocations (by object, `alloc_objects`) in a geospatial query of interest:

```
Type: alloc_objects
Time: Aug 21, 2020 at 4:59pm (UTC)
Active filters:
   focus=geoKeyToEncInvertedVal
Showing nodes accounting for 61277094, 27.52% of 222698492 total
----------------------------------------------------------+-------------
      flat  flat%   sum%        cum   cum%   calls calls% + context
----------------------------------------------------------+-------------
                                          15270121 99.79% |   github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoToSpan /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:46
                                             32768  0.21% |   github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoToSpan /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:45
  15302889  6.87%  6.87%   15302889  6.87%                | github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoKeyToEncInvertedVal /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:31
----------------------------------------------------------+-------------
                                          16187639 53.52% |   github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoToSpan /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:46
                                          14057686 46.48% |   github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoToSpan /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:45
         0     0%  6.87%   30245325 13.58%                | github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoKeyToEncInvertedVal /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:32
                                          30245325   100% |   github.com/cockroachdb/cockroach/pkg/sql/sqlbase.EncodeTableKey /go/src/github.com/cockroachdb/cockroach/pkg/sql/sqlbase/column_type_encoding.go:75
----------------------------------------------------------+-------------
                                          15728880   100% |   github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoToSpan /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:46
         0     0%  6.87%   15728880  7.06%                | github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoKeyToEncInvertedVal /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:38
                                          15728880   100% |   github.com/cockroachdb/cockroach/pkg/roachpb.Key.PrefixEnd /go/src/github.com/cockroachdb/cockroach/pkg/roachpb/data.go:188
----------------------------------------------------------+-------------
```

These allocations were largely avoidable. This commit removes some of
them entirely and reworks the code structure in order to amortize the
unavoidable allocations over the set of keys being encoded. The result
is a large reduction in allocations. On the same workload, allocations
under `geoKeyToEncInvertedVal` dropped from **27.52%** of the workload
to **2.23%** of the workload:

```
Type: alloc_objects
Time: Aug 21, 2020 at 5:04pm (UTC)
Active filters:
   focus=geoKeyToEncInvertedVal
Showing nodes accounting for 3632555, 2.23% of 162651628 total
----------------------------------------------------------+-------------
      flat  flat%   sum%        cum   cum%   calls calls% + context
----------------------------------------------------------+-------------
                                           2014518 55.46% |   github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoToSpan /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:53
                                           1618037 44.54% |   github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoToSpan /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:54
         0     0%     0%    3632555  2.23%                | github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoKeyToEncInvertedVal /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:44
                                           3632555   100% |   github.com/cockroachdb/cockroach/pkg/util/encoding.EncodeUvarintAscending /go/src/github.com/cockroachdb/cockroach/pkg/util/encoding/encoding.go:375
----------------------------------------------------------+-------------
```

When applied on top of cockroachdb#53181, this results in a **1.71%** speedup on
the following geospatial query:

```sql
SELECT Count(census.blkid), Count(subways.name)
FROM nyc_census_blocks AS census
JOIN nyc_subway_stations AS subways
ON ST_Intersects(subways.geom, census.geom);
```

```
name                                old ms    new ms    delta
Test/postgis_geometry_tutorial/nyc  136 ±12%  134 ±11%  -1.71%  (p=0.000 n=976+977)
```

In making this change, we also fix a bug where `geoindex.Key` (a uint64) was
being cast to a `tree.DInt` (an int64) during encoding. This could result in
overflow and could cause inverted key spans to be generated.
craig bot pushed a commit that referenced this pull request Aug 21, 2020
46407: kvcoord: small fixes r=andreimatei a=andreimatei

See individual commits.

52740: sql: owning a schema gives privilege to drop tables in schema r=RichardJCai a=RichardJCai

sql: owning a schema gives privilege to drop tables in schema

Release note (sql change): Schema owners can drop tables inside
the schema without explicit DROP privilege on the table.

Fixes #51931

53127: builtins: use ST_Union as aggregate r=rytaft,sumeerbhola a=otan

Add the ST_Union aggregate, removing the two-argument version
temporarily as we cannot currently have an aggregate and non-aggregate
at the same time. This is ok since we haven't released yet, and from
reading it seems more likely people will use the aggregate version.

Release note (sql change): Implement the ST_Union builtin as an
aggregate. The previous alpha-available ST_Union for two arguments is
deprecated.

53162: builtins: implement ST_GeomFromGeoHash/ST_Box2DFromGeoHash r=sumeerbhola a=otan

Resolves #48806

Release note (sql change): Implemented the ST_GeomFromGeoHash and
ST_Box2DFromGeoHash builtins.

53181: sql/kv: avoid expensive heap allocations with inverted joins r=nvanbenschoten a=nvanbenschoten

This PR contains three optimizations that reduce heap allocations by
inverted join operations. These were found by profiling the following
geospatial query:
```sql
SELECT Count(census.blkid), Count(subways.name)
FROM nyc_census_blocks AS census
JOIN nyc_subway_stations AS subways
ON ST_Intersects(subways.geom, census.geom);
```

Combined, these three commits speed up the query by a little over **3%**.

```
name                                old ms    new ms    delta
Test/postgis_geometry_tutorial/nyc  139 ±12%  135 ±11%  -3.04%  (p=0.000 n=241+243)
```

#### sql/rowexec: avoid heap allocations in batchedInvertedExprEvaluator

This commit restructures the slice manipulation performed in
`(*batchedInvertedExprEvaluator).init` to avoid heap allocations. Before
the change, this method used to contain the first and fifth most
expensive memory allocations by total allocation size (`alloc_space`)
in a geospatial query of interest:
```
----------------------------------------------------------+-------------
                                         3994.06MB   100% |   github.com/cockroachdb/cockroach/pkg/sql/rowexec.(*invertedJoiner).readInput /go/src/github.com/cockroachdb/cockroach/pkg/sql/rowexec/inverted_joiner.go:418
 3994.06MB 10.70% 10.70%  3994.06MB 10.70%                | github.com/cockroachdb/cockroach/pkg/sql/rowexec.(*batchedInvertedExprEvaluator).init /go/src/github.com/cockroachdb/cockroach/pkg/sql/rowexec/inverted_expr_evaluator.go:366
----------------------------------------------------------+-------------

----------------------------------------------------------+-------------
                                          954.07MB   100% |   github.com/cockroachdb/cockroach/pkg/sql/rowexec.(*invertedJoiner).readInput /go/src/github.com/cockroachdb/cockroach/pkg/sql/rowexec/inverted_joiner.go:418
  954.07MB  4.61% 41.71%   954.07MB  4.61%                | github.com/cockroachdb/cockroach/pkg/sql/rowexec.(*batchedInvertedExprEvaluator).init /go/src/github.com/cockroachdb/cockroach/pkg/sql/rowexec/inverted_expr_evaluator.go:409
----------------------------------------------------------+-------------
```

The largest offender here was the `routingSpans` slice, which made no
attempt to recycle memory. The other offender was the `pendingSpans`
slice. We made an attempt to recycle the memory in this slice, except
we truncated it from the front instead of the back, so we ended us
not actually recycling anything.

This commit addresses this in two ways. First, it updates the `pendingSpans`
slice to point into the `routingSpans` slice so the two can share memory.
`pendingSpans` becomes a mutable window into `routingSpans`, so it no
longer requires its own heap allocation. Next, the commit updates the
memory recycling to recycle `routingSpans` instead of `pendingSpans`.
Since we never truncate `routingSpans` from the front, the recycling
now works.

With these two changes, the two heap allocations, which used to account
for **15.31%** of total allocated space combined drops to a single heap
allocation that accounts for only **2.43%** of total allocated space on
the geospatial query.

```
----------------------------------------------------------+-------------
                                          182.62MB   100% |   github.com/cockroachdb/cockroach/pkg/sql/rowexec.(*invertedJoiner).readInput /go/src/github.com/cockroachdb/cockroach/pkg/sql/rowexec/inverted_joiner.go:418
  182.62MB  2.43% 58.36%   182.62MB  2.43%                | github.com/cockroachdb/cockroach/pkg/sql/rowexec.(*batchedInvertedExprEvaluator).init /go/src/github.com/cockroachdb/cockroach/pkg/sql/rowexec/inverted_expr_evaluator.go:366
----------------------------------------------------------+-------------
```

#### sql: properly copy span slices

This commit fixes two locations where we not optimally performing copies
from one slice to another.

In `invertedJoiner.generateSpans`, we were not pre-allocating the
destination slice and were using append instead of direct assignment,
which is measurably slower due to the extra writes to the slice header.

In `getProtoSpans`, we again were appending to a slice with zero length
and sufficient capacity instead of assigning to a slice with sufficient
length.

#### kv: check for expensive logging before VEventf in appendRefreshSpans

Before this change, we called VEventf directly with the refresh span
corresponding to each request in a batch. This caused each span object
to allocate while passing through an `interface{}`. This could be seen
in heap profiles, where it accounted for **1.89%** of total allocated
memory (`alloc_space`) in a geospatial query of interest:

```
----------------------------------------------------------+-------------
                                          142.01MB   100% |   github.com/cockroachdb/cockroach/pkg/roachpb.(*BatchRequest).RefreshSpanIterate /go/src/github.com/cockroachdb/cockroach/pkg/roachpb/batch.go:407
  142.01MB  1.89% 68.71%   142.01MB  1.89%                | github.com/cockroachdb/cockroach/pkg/kv/kvclient/kvcoord.(*txnSpanRefresher).appendRefreshSpans.func1 /go/src/github.com/cockroachdb/cockroach/pkg/kv/kvclient/kvcoord/txn_interceptor_span_refresher.go:510
----------------------------------------------------------+-------------
```

This commit adds a guard around the VEventf to avoid the allocation.

53196: sqlliveness/slstorage,timeutil: various improvements r=spaskob a=ajwerner

See individual commits. This PR addresses some anxieties I had about the implementation of slstorage. In particular, it makes the testing deterministic by giving it a new table independent of the host cluster's state and allows injecting time. It then changes the GC to be less frequent and instead relies on failing out sessions when it determines they are expired. This is important to avoid spinning between when a session is deemed expired and when it would later be deleted by a gc interval. It also jitters that GC interval to avoid problems due to contention in larger clusters. 

53214: serverpb: add docstrings to `HotRangesRequest` and `HotRangesResponse` r=mjibson a=knz

This is part of a project to document the public HTTP APIs.

@mjibson you'll notice in this PR that the doc generator doesn't deal well with newline characters in docstrings.

Co-authored-by: Andrei Matei <[email protected]>
Co-authored-by: richardjcai <[email protected]>
Co-authored-by: Oliver Tan <[email protected]>
Co-authored-by: Nathan VanBenschoten <[email protected]>
Co-authored-by: Andrew Werner <[email protected]>
Co-authored-by: Raphael 'kena' Poss <[email protected]>
nvanbenschoten added a commit to nvanbenschoten/cockroach that referenced this pull request Aug 21, 2020
…oSpanExpr

This commit optimizes a few heap allocations in `GeoUnionKeySpansToSpanExpr` and
in `GeoRPKeyExprToSpanExpr` to avoid per-span/per-expression heap allocations.

Before this change, these heap allocations accounted for 27.52% of all heap
allocations (by object, `alloc_objects`) in a geospatial query of interest:

```
Type: alloc_objects
Time: Aug 21, 2020 at 4:59pm (UTC)
Active filters:
   focus=geoKeyToEncInvertedVal
Showing nodes accounting for 61277094, 27.52% of 222698492 total
----------------------------------------------------------+-------------
      flat  flat%   sum%        cum   cum%   calls calls% + context
----------------------------------------------------------+-------------
                                          15270121 99.79% |   github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoToSpan /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:46
                                             32768  0.21% |   github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoToSpan /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:45
  15302889  6.87%  6.87%   15302889  6.87%                | github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoKeyToEncInvertedVal /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:31
----------------------------------------------------------+-------------
                                          16187639 53.52% |   github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoToSpan /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:46
                                          14057686 46.48% |   github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoToSpan /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:45
         0     0%  6.87%   30245325 13.58%                | github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoKeyToEncInvertedVal /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:32
                                          30245325   100% |   github.com/cockroachdb/cockroach/pkg/sql/sqlbase.EncodeTableKey /go/src/github.com/cockroachdb/cockroach/pkg/sql/sqlbase/column_type_encoding.go:75
----------------------------------------------------------+-------------
                                          15728880   100% |   github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoToSpan /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:46
         0     0%  6.87%   15728880  7.06%                | github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoKeyToEncInvertedVal /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:38
                                          15728880   100% |   github.com/cockroachdb/cockroach/pkg/roachpb.Key.PrefixEnd /go/src/github.com/cockroachdb/cockroach/pkg/roachpb/data.go:188
----------------------------------------------------------+-------------
```

These allocations were largely avoidable. This commit removes some of
them entirely and reworks the code structure in order to amortize the
unavoidable allocations over the set of keys being encoded. The result
is a large reduction in allocations. On the same workload, allocations
under `geoKeyToEncInvertedVal` dropped from **27.52%** of the workload
to **2.23%** of the workload:

```
Type: alloc_objects
Time: Aug 21, 2020 at 5:04pm (UTC)
Active filters:
   focus=geoKeyToEncInvertedVal
Showing nodes accounting for 3632555, 2.23% of 162651628 total
----------------------------------------------------------+-------------
      flat  flat%   sum%        cum   cum%   calls calls% + context
----------------------------------------------------------+-------------
                                           2014518 55.46% |   github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoToSpan /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:53
                                           1618037 44.54% |   github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoToSpan /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:54
         0     0%     0%    3632555  2.23%                | github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoKeyToEncInvertedVal /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:44
                                           3632555   100% |   github.com/cockroachdb/cockroach/pkg/util/encoding.EncodeUvarintAscending /go/src/github.com/cockroachdb/cockroach/pkg/util/encoding/encoding.go:375
----------------------------------------------------------+-------------
```

When applied on top of cockroachdb#53181, this results in a **1.71%** speedup on
the following geospatial query:

```sql
SELECT Count(census.blkid), Count(subways.name)
FROM nyc_census_blocks AS census
JOIN nyc_subway_stations AS subways
ON ST_Intersects(subways.geom, census.geom);
```

```
name                                old ms    new ms    delta
Test/postgis_geometry_tutorial/nyc  136 ±12%  134 ±11%  -1.71%  (p=0.000 n=976+977)
```

In making this change, we also fix a bug where `geoindex.Key` (a uint64) was
being cast to a `tree.DInt` (an int64) during encoding. This could result in
overflow and could cause inverted key spans to be generated.
@craig
Copy link
Contributor

craig bot commented Aug 21, 2020

Build failed (retrying...):

nvanbenschoten added a commit to nvanbenschoten/cockroach that referenced this pull request Aug 21, 2020
This commit updates batchedInvertedExprEvaluator to recycle the `[]invertedSpan`
that it constructs in its init method, such that the same slice can be reused
for each batch of rows in the `invertedJoiner`.

Before this change, this heap allocations accounted for 5.51% of all heap
allocations (by size, `alloc_space`) in a geospatial query of interest:

```
----------------------------------------------------------+-------------
                                             804MB   100% |   github.com/cockroachdb/cockroach/pkg/sql/rowexec.(*invertedJoiner).readInput /go/src/github.com/cockroachdb/cockroach/pkg/sql/rowexec/inverted_joiner.go:418
     804MB  5.51% 36.69%      804MB  5.51%                | github.com/cockroachdb/cockroach/pkg/sql/rowexec.(*batchedInvertedExprEvaluator).init /go/src/github.com/cockroachdb/cockroach/pkg/sql/rowexec/inverted_expr_evaluator.go:407
----------------------------------------------------------+-------------
```

When applied on top of cockroachdb#53181 and cockroachdb#53215, this results in a 0.4% speedup on
the following geospatial query:

```sql
SELECT Count(census.blkid), Count(subways.name)
FROM nyc_census_blocks AS census
JOIN nyc_subway_stations AS subways
ON ST_Intersects(subways.geom, census.geom);
```

```
name                                old ms    new ms    delta
Test/postgis_geometry_tutorial/nyc  134 ±12%  133 ±12%  -0.40%  (p=0.006 n=976+979)
```
@craig
Copy link
Contributor

craig bot commented Aug 22, 2020

This PR was included in a batch that was canceled, it will be automatically retried

@craig
Copy link
Contributor

craig bot commented Aug 22, 2020

Build succeeded:

@craig craig bot merged commit 7621d40 into cockroachdb:master Aug 22, 2020
nvanbenschoten added a commit to nvanbenschoten/cockroach that referenced this pull request Aug 22, 2020
This commit updates batchedInvertedExprEvaluator to recycle the `[]invertedSpan`
that it constructs in its init method, such that the same slice can be reused
for each batch of rows in the `invertedJoiner`.

Before this change, this heap allocations accounted for 5.51% of all heap
allocations (by size, `alloc_space`) in a geospatial query of interest:

```
----------------------------------------------------------+-------------
                                             804MB   100% |   github.com/cockroachdb/cockroach/pkg/sql/rowexec.(*invertedJoiner).readInput /go/src/github.com/cockroachdb/cockroach/pkg/sql/rowexec/inverted_joiner.go:418
     804MB  5.51% 36.69%      804MB  5.51%                | github.com/cockroachdb/cockroach/pkg/sql/rowexec.(*batchedInvertedExprEvaluator).init /go/src/github.com/cockroachdb/cockroach/pkg/sql/rowexec/inverted_expr_evaluator.go:407
----------------------------------------------------------+-------------
```

When applied on top of cockroachdb#53181 and cockroachdb#53215, this results in a 0.4% speedup on
the following geospatial query:

```sql
SELECT Count(census.blkid), Count(subways.name)
FROM nyc_census_blocks AS census
JOIN nyc_subway_stations AS subways
ON ST_Intersects(subways.geom, census.geom);
```

```
name                                old ms    new ms    delta
Test/postgis_geometry_tutorial/nyc  134 ±12%  133 ±12%  -0.40%  (p=0.006 n=976+979)
```
@nvanbenschoten nvanbenschoten deleted the nvanbenschoten/batchedInvertedExprEvaluator2 branch August 22, 2020 03:24
craig bot pushed a commit that referenced this pull request Aug 22, 2020
53237: sql/rowexec: recycle coveringSpans in batchedInvertedExprEvaluator r=nvanbenschoten a=nvanbenschoten

This commit updates batchedInvertedExprEvaluator to recycle the []invertedSpan
that it constructs in its init method, such that the same slice can be reused
for each batch of rows in the `invertedJoiner`.

Before this change, this heap allocations accounted for 5.51% of all heap
allocations (by size, `alloc_space`) in a geospatial query of interest:

```
----------------------------------------------------------+-------------
                                             804MB   100% |   github.com/cockroachdb/cockroach/pkg/sql/rowexec.(*invertedJoiner).readInput /go/src/github.com/cockroachdb/cockroach/pkg/sql/rowexec/inverted_joiner.go:418
     804MB  5.51% 36.69%      804MB  5.51%                | github.com/cockroachdb/cockroach/pkg/sql/rowexec.(*batchedInvertedExprEvaluator).init /go/src/github.com/cockroachdb/cockroach/pkg/sql/rowexec/inverted_expr_evaluator.go:407
----------------------------------------------------------+-------------
```

When applied on top of #53181 and #53215, this results in a **0.4%** speedup on
the following geospatial query:

```sql
SELECT Count(census.blkid), Count(subways.name)
FROM nyc_census_blocks AS census
JOIN nyc_subway_stations AS subways
ON ST_Intersects(subways.geom, census.geom);
```

```
name                                old ms    new ms    delta
Test/postgis_geometry_tutorial/nyc  134 ±12%  133 ±12%  -0.40%  (p=0.006 n=976+979)
```

Co-authored-by: Nathan VanBenschoten <[email protected]>
nvanbenschoten added a commit to nvanbenschoten/cockroach that referenced this pull request Aug 23, 2020
…oSpanExpr

This commit optimizes a few heap allocations in `GeoUnionKeySpansToSpanExpr` and
in `GeoRPKeyExprToSpanExpr` to avoid per-span/per-expression heap allocations.

Before this change, these heap allocations accounted for 27.52% of all heap
allocations (by object, `alloc_objects`) in a geospatial query of interest:

```
Type: alloc_objects
Time: Aug 21, 2020 at 4:59pm (UTC)
Active filters:
   focus=geoKeyToEncInvertedVal
Showing nodes accounting for 61277094, 27.52% of 222698492 total
----------------------------------------------------------+-------------
      flat  flat%   sum%        cum   cum%   calls calls% + context
----------------------------------------------------------+-------------
                                          15270121 99.79% |   github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoToSpan /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:46
                                             32768  0.21% |   github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoToSpan /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:45
  15302889  6.87%  6.87%   15302889  6.87%                | github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoKeyToEncInvertedVal /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:31
----------------------------------------------------------+-------------
                                          16187639 53.52% |   github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoToSpan /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:46
                                          14057686 46.48% |   github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoToSpan /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:45
         0     0%  6.87%   30245325 13.58%                | github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoKeyToEncInvertedVal /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:32
                                          30245325   100% |   github.com/cockroachdb/cockroach/pkg/sql/sqlbase.EncodeTableKey /go/src/github.com/cockroachdb/cockroach/pkg/sql/sqlbase/column_type_encoding.go:75
----------------------------------------------------------+-------------
                                          15728880   100% |   github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoToSpan /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:46
         0     0%  6.87%   15728880  7.06%                | github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoKeyToEncInvertedVal /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:38
                                          15728880   100% |   github.com/cockroachdb/cockroach/pkg/roachpb.Key.PrefixEnd /go/src/github.com/cockroachdb/cockroach/pkg/roachpb/data.go:188
----------------------------------------------------------+-------------
```

These allocations were largely avoidable. This commit removes some of
them entirely and reworks the code structure in order to amortize the
unavoidable allocations over the set of keys being encoded. The result
is a large reduction in allocations. On the same workload, allocations
under `geoKeyToEncInvertedVal` dropped from **27.52%** of the workload
to **2.23%** of the workload:

```
Type: alloc_objects
Time: Aug 21, 2020 at 5:04pm (UTC)
Active filters:
   focus=geoKeyToEncInvertedVal
Showing nodes accounting for 3632555, 2.23% of 162651628 total
----------------------------------------------------------+-------------
      flat  flat%   sum%        cum   cum%   calls calls% + context
----------------------------------------------------------+-------------
                                           2014518 55.46% |   github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoToSpan /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:53
                                           1618037 44.54% |   github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoToSpan /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:54
         0     0%     0%    3632555  2.23%                | github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoKeyToEncInvertedVal /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:44
                                           3632555   100% |   github.com/cockroachdb/cockroach/pkg/util/encoding.EncodeUvarintAscending /go/src/github.com/cockroachdb/cockroach/pkg/util/encoding/encoding.go:375
----------------------------------------------------------+-------------
```

When applied on top of cockroachdb#53181, this results in a **1.71%** speedup on
the following geospatial query:

```sql
SELECT Count(census.blkid), Count(subways.name)
FROM nyc_census_blocks AS census
JOIN nyc_subway_stations AS subways
ON ST_Intersects(subways.geom, census.geom);
```

```
name                                old ms    new ms    delta
Test/postgis_geometry_tutorial/nyc  136 ±12%  134 ±11%  -1.71%  (p=0.000 n=976+977)
```

In making this change, we also fix a bug where `geoindex.Key` (a uint64) was
being cast to a `tree.DInt` (an int64) during encoding. This could result in
overflow and could cause inverted key spans to be generated.
craig bot pushed a commit that referenced this pull request Aug 24, 2020
52972: cli: command to deserialize descriptors r=spaskob a=spaskob

We currently export the descriptors and job payloads in debug zips with
hex encoding.  It is often very valuable to decode these protos into
JSON for inspection.

Fixes #52063.

Release note (cli change):
The new debug command `decode-proto` reads descriptor from stdin in hex
or base64 format (auto-detected) and a flag --schema=\<fully qualified name to decode\>
with default value `cockroach.sql.sqlbase.Descriptor` and outputs to stdout the
deserialized proto in JSON format.

53226: colexec: make hash table more dynamic and fix hash join in some cases r=yuzefovich a=yuzefovich

**colexec: make hash table more dynamic**

This commit replaces all fixed allocations of constant size in the hash
table in favor of allocating the slices dynamically which makes the hash
table more dynamic as well. This allows us to place the logic of
clearing up those slices for the next iteration in a single place which
simplifies the code a bit.

Additionally it moves `buckets` slice that is only used by the hash
joiner out of the hash table.

Release note: None

**colexec: fix LEFT ANTI hash join when right eq cols are key**

Release note (bug fix): Previously, CockroachDB could return incorrect
results when performing LEFT ANTI hash join when right equality columns
form a key when it was executed via the vectorized engine, and now this
has been fixed.

**colexec: fix set-op hash joins and optimize them a bit**

This commit fixes several problems with set-operation hash joins:
1. similar to how LEFT ANTI hash joins are handled, INTERSECT ALL and
EXCEPT ALL hash joins rely on `headID` to be populated. That step is
skipped if the right side is distinct (meaning right equality columns
form a key). This would result in incorrect output, and we now override
`rightDistinct` flag to get the desired behavior (probably sub-optimal
but correct).
2. actually, before we would get an incorrect result, we would hit an
out of bounds error because `hashTable.visited` would not have been
created previously. That slice is used by set-op joins to track which
tuples from the right side have already been "deleted" (i.e. they were
used for a match). This is now also fixed.

However, currently the information whether the right equality columns
form a key is not propagated for set-operation joins, so the bug would
not have occurred in the non-test environment.

Additionally, this commit optimizes the handling of LEFT ANTI and EXCEPT
ALL joins by not allocating `same` slice because those two join types
have separate `collectAnti*` methods that don't use that slice.

Release note: None

53248: release: fix adding libgeos files to .tar.gz and compress .zip r=jlinder a=otan

* Fix issue where only the first file was added to a .tar.gz.
* Compress files better when adding to zips.

Release note: None

53252: sql/kv: optimize heap allocations for inverted joins and scans with many spans r=nvanbenschoten a=nvanbenschoten

This PR contains a collection of optimizations that build on #53181,
#53215, and #53237 to reduce the number and size of heap allocations
performed by inverted joins.

Combined, these changes results in a **1.46%** speedup on the following
geospatial query:
```sql
SELECT Count(census.blkid), Count(subways.name)
FROM nyc_census_blocks AS census
JOIN nyc_subway_stations AS subways
ON ST_Intersects(subways.geom, census.geom);
```
```
name                                old ms    new ms    delta
Test/postgis_geometry_tutorial/nyc  144 ±15%  142 ±16%  -1.46%  (p=0.000 n=972+974)
```

----

### kv: reserve lock spans in SpanSet ahead of time

In #52610, we merged the latch and lock span declared by requests. Doing
so is the long term goal in this area, but it doesn't seem like that's
going to be possible for v20.2. Meanwhile, the collection of lock spans
is currently less efficient than the collection of latch spans. This is
because we have a heuristic to eagerly allocate lock span slices ahead
of time, instead of letting them grow as they are appended to. This
optimization does not exist for lock spans.

We can see this by looking at an alloc_space heap profile while running
a geospatial query of interest. We see that the lock spans account for
**9.76%** of all allocated space while the latch spans account for only
**2.65%** of all allocated space.

```
----------------------------------------------------------+-------------
                                          646.37MB   100% |   github.com/cockroachdb/cockroach/pkg/kv/kvserver/batcheval.DefaultDeclareIsolatedKeys /go/src/github.com/cockroachdb/cockroach/pkg/kv/kvserver/batcheval/declare.go:90
         0     0%   100%   646.37MB  9.76%                | github.com/cockroachdb/cockroach/pkg/kv/kvserver/spanset.(*SpanSet).AddNonMVCC /go/src/github.com/cockroachdb/cockroach/pkg/kv/kvserver/spanset/spanset.go:127
                                          646.37MB   100% |   github.com/cockroachdb/cockroach/pkg/kv/kvserver/spanset.(*SpanSet).AddMVCC /go/src/github.com/cockroachdb/cockroach/pkg/kv/kvserver/spanset/spanset.go:139
----------------------------------------------------------+-------------
                                          175.37MB   100% |   github.com/cockroachdb/cockroach/pkg/kv/kvserver.(*Replica).collectSpans /go/src/github.com/cockroachdb/cockroach/pkg/kv/kvserver/replica_send.go:691
  175.37MB  2.65% 61.51%   175.37MB  2.65%                | github.com/cockroachdb/cockroach/pkg/kv/kvserver/spanset.(*SpanSet).Reserve /go/src/github.com/cockroachdb/cockroach/pkg/kv/kvserver/spanset/spanset.go:120
----------------------------------------------------------+-------------
```

To improve this, we can do the same ahead of time slice resizing for
lock spans by reserving an estimate for the number and type of lock
spans we expect a request to declare. This guess may be a little less
accurate than our guess for latch spans, because there are a few request
types that declare latch spans but not lock spans, but these are rare
requests that are much less important to optimize than the requests that
do declare a latch and a lock span.

With this change, we shave off about **6.57%** of total allocated space
in this workload. We no longer see allocations in `SpanSet.AddNonMVCC`
and the amount of heap memory allocated by `SpanSet.Reserve` roughly
doubles, as we would expect.

```
----------------------------------------------------------+-------------
                                          190.99MB 53.34% |   github.com/cockroachdb/cockroach/pkg/kv/kvserver.(*Replica).collectSpans /go/src/github.com/cockroachdb/cockroach/pkg/kv/kvserver/replica_send.go:692
                                          167.09MB 46.66% |   github.com/cockroachdb/cockroach/pkg/kv/kvserver.(*Replica).collectSpans /go/src/github.com/cockroachdb/cockroach/pkg/kv/kvserver/replica_send.go:693
  358.08MB  5.84% 36.53%   358.08MB  5.84%                | github.com/cockroachdb/cockroach/pkg/kv/kvserver/spanset.(*SpanSet).Reserve /go/src/github.com/cockroachdb/cockroach/pkg/kv/kvserver/spanset/spanset.go:120
----------------------------------------------------------+-------------
```

### sql/row: batch allocate RequestUnion wrapper structs in txnKVFetcher.fetch

A Request's approach towards representing a union type results in double
indirection. For instance, a ScanRequest is represented like:
```
Request{Value: &RequestUnion_Scan{Scan: &ScanRequest{}}}
```

The code in txnKVFetcher.fetch was batch allocating the inner struct in
this structure across all scans in a batch, but was not batch allocating
the outer "union" struct. The effect of this is that the outer struct's
heap allocation showed up as 4.78% of the alloc_objects heap profile of
an interesting geospatial query:

```
----------------------------------------------------------+-------------
                                           2621460   100% |   github.com/cockroachdb/cockroach/pkg/sql/row.(*txnKVFetcher).fetch /go/src/github.com/cockroachdb/cockroach/pkg/sql/row/kv_batch_fetcher.go:297
         0     0%   100%    2621460  4.78%                | github.com/cockroachdb/cockroach/pkg/roachpb.(*RequestUnion).MustSetInner /go/src/github.com/cockroachdb/cockroach/pkg/roachpb/api.go:604
                                           2621460   100% |   github.com/cockroachdb/cockroach/pkg/roachpb.(*RequestUnion).SetInner /go/src/github.com/cockroachdb/cockroach/pkg/roachpb/batch_generated.go:354
----------------------------------------------------------+-------------
```

This commit avoids this source of per-request allocations by batch
allocating these union structs across all requests in a batch just
like the code was previously batch allocating the inner structs.

### sql/rowexec: avoid allocating slice header on sort in fragmentPendingSpans

batchedInvertedExprEvaluator's fragmentPendingSpans performs a
`sort.Slice` to sort a list of pending spans by their end key.
`sort.Slice` is convenient, but it has some trade-offs. For one, it uses
reflection to mimic parameterization over all slice types. Second, it
accepts the slice as an interface, which causes the slice header to
escape to the heap.

The effect of this is that the call was showing up as 4.35% of the
alloc_objects heap profile of an interesting geospatial query:

```
----------------------------------------------------------+-------------
                                           2387773   100% |   github.com/cockroachdb/cockroach/pkg/sql/rowexec.(*batchedInvertedExprEvaluator).init /go/src/github.com/cockroachdb/cockroach/pkg/sql/rowexec/inverted_expr_evaluator.go:406
   2162754  3.94% 40.58%    2387773  4.35%                | github.com/cockroachdb/cockroach/pkg/sql/rowexec.(*batchedInvertedExprEvaluator).fragmentPendingSpans /go/src/github.com/cockroachdb/cockroach/pkg/sql/rowexec/inverted_expr_evaluator.go:284
                                            225019  9.42% |   sort.Slice /usr/local/go/src/sort/slice.go:15
----------------------------------------------------------+-------------
```

This commit avoids this heap allocation by assigning the slice to a
field on the batchedInvertedExprEvaluator (which was already on the
heap) and using the old `sort.Sort` function.

----

@otan an area I didn't touch but wanted to talk to you about was the
memory representation of `DGeography` and `DGeometry`. Specifically, I'm
wondering why we're embedding pointers instead of values inside of these
datums, effectively creating a double-boxing situation. I see that most
of the geo operators work off pointer and that the "canonical"
representation of the objects exported by `pkg/geo` is a pointer (e.g.
the package exports "New..." methods instead of "Make..." methods). I
don't understand why this is though. Both `Geography` and `Geometry` are
only 40 bytes large, which is well within reason to pass on the stack.

I ask because this makes working with these datums more expensive than
strictly necessary. We make an effort to batch allocate datum objects
themselves (see `DatumAlloc`), but don't do anything special with
internal heap allocations. I suspect that there would be a moderate win
here if we eliminated the double-boxing on any query that scans a large
number of rows containing one of these data types, as I'm seeing the
heap allocations in DecodeUntaggedDatum fairly prominently in profiles.

Co-authored-by: Spas Bojanov <[email protected]>
Co-authored-by: Yahor Yuzefovich <[email protected]>
Co-authored-by: Oliver Tan <[email protected]>
Co-authored-by: Nathan VanBenschoten <[email protected]>
nvanbenschoten added a commit to nvanbenschoten/cockroach that referenced this pull request Aug 24, 2020
…oSpanExpr

This commit optimizes a few heap allocations in `GeoUnionKeySpansToSpanExpr` and
in `GeoRPKeyExprToSpanExpr` to avoid per-span/per-expression heap allocations.

Before this change, these heap allocations accounted for 27.52% of all heap
allocations (by object, `alloc_objects`) in a geospatial query of interest:

```
Type: alloc_objects
Time: Aug 21, 2020 at 4:59pm (UTC)
Active filters:
   focus=geoKeyToEncInvertedVal
Showing nodes accounting for 61277094, 27.52% of 222698492 total
----------------------------------------------------------+-------------
      flat  flat%   sum%        cum   cum%   calls calls% + context
----------------------------------------------------------+-------------
                                          15270121 99.79% |   github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoToSpan /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:46
                                             32768  0.21% |   github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoToSpan /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:45
  15302889  6.87%  6.87%   15302889  6.87%                | github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoKeyToEncInvertedVal /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:31
----------------------------------------------------------+-------------
                                          16187639 53.52% |   github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoToSpan /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:46
                                          14057686 46.48% |   github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoToSpan /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:45
         0     0%  6.87%   30245325 13.58%                | github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoKeyToEncInvertedVal /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:32
                                          30245325   100% |   github.com/cockroachdb/cockroach/pkg/sql/sqlbase.EncodeTableKey /go/src/github.com/cockroachdb/cockroach/pkg/sql/sqlbase/column_type_encoding.go:75
----------------------------------------------------------+-------------
                                          15728880   100% |   github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoToSpan /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:46
         0     0%  6.87%   15728880  7.06%                | github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoKeyToEncInvertedVal /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:38
                                          15728880   100% |   github.com/cockroachdb/cockroach/pkg/roachpb.Key.PrefixEnd /go/src/github.com/cockroachdb/cockroach/pkg/roachpb/data.go:188
----------------------------------------------------------+-------------
```

These allocations were largely avoidable. This commit removes some of
them entirely and reworks the code structure in order to amortize the
unavoidable allocations over the set of keys being encoded. The result
is a large reduction in allocations. On the same workload, allocations
under `geoKeyToEncInvertedVal` dropped from **27.52%** of the workload
to **2.23%** of the workload:

```
Type: alloc_objects
Time: Aug 21, 2020 at 5:04pm (UTC)
Active filters:
   focus=geoKeyToEncInvertedVal
Showing nodes accounting for 3632555, 2.23% of 162651628 total
----------------------------------------------------------+-------------
      flat  flat%   sum%        cum   cum%   calls calls% + context
----------------------------------------------------------+-------------
                                           2014518 55.46% |   github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoToSpan /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:53
                                           1618037 44.54% |   github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoToSpan /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:54
         0     0%     0%    3632555  2.23%                | github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoKeyToEncInvertedVal /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:44
                                           3632555   100% |   github.com/cockroachdb/cockroach/pkg/util/encoding.EncodeUvarintAscending /go/src/github.com/cockroachdb/cockroach/pkg/util/encoding/encoding.go:375
----------------------------------------------------------+-------------
```

When applied on top of cockroachdb#53181, this results in a **1.71%** speedup on
the following geospatial query:

```sql
SELECT Count(census.blkid), Count(subways.name)
FROM nyc_census_blocks AS census
JOIN nyc_subway_stations AS subways
ON ST_Intersects(subways.geom, census.geom);
```

```
name                                old ms    new ms    delta
Test/postgis_geometry_tutorial/nyc  136 ±12%  134 ±11%  -1.71%  (p=0.000 n=976+977)
```

In making this change, we also fix a bug where `geoindex.Key` (a uint64) was
being cast to a `tree.DInt` (an int64) during encoding. This could result in
overflow and could cause inverted key spans to be generated.
craig bot pushed a commit that referenced this pull request Aug 25, 2020
53153: colexec: clean up vectorized stats r=yuzefovich a=yuzefovich

Release note (sql change): `selectivity` information has been removed
from EXPLAIN ANALYZE diagrams which would be present if the query was
executed via the vectorized engine because it has been quite confusing
and probably not helpful information.

Release note (sql change): `stall time` has been renamed to
`IO + execution time` in EXPLAIN ANALYZE diagrams for the queries that are
executed via the vectorized engine.

53215: sql/opt/invertedexpr: avoid per-span allocations in GeoUnionKeySpansToSpanExpr r=nvanbenschoten a=nvanbenschoten

This commit optimizes a few heap allocations in `GeoUnionKeySpansToSpanExpr` and
in `GeoRPKeyExprToSpanExpr` to avoid per-span/per-expression heap allocations.

Before this change, these heap allocations accounted for 27.52% of all heap
allocations (by object, `alloc_objects`) in a geospatial query of interest:

```
Type: alloc_objects
Time: Aug 21, 2020 at 4:59pm (UTC)
Active filters:
   focus=geoKeyToEncInvertedVal
Showing nodes accounting for 61277094, 27.52% of 222698492 total
----------------------------------------------------------+-------------
      flat  flat%   sum%        cum   cum%   calls calls% + context
----------------------------------------------------------+-------------
                                          15270121 99.79% |   github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoToSpan /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:46
                                             32768  0.21% |   github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoToSpan /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:45
  15302889  6.87%  6.87%   15302889  6.87%                | github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoKeyToEncInvertedVal /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:31
----------------------------------------------------------+-------------
                                          16187639 53.52% |   github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoToSpan /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:46
                                          14057686 46.48% |   github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoToSpan /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:45
         0     0%  6.87%   30245325 13.58%                | github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoKeyToEncInvertedVal /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:32
                                          30245325   100% |   github.com/cockroachdb/cockroach/pkg/sql/sqlbase.EncodeTableKey /go/src/github.com/cockroachdb/cockroach/pkg/sql/sqlbase/column_type_encoding.go:75
----------------------------------------------------------+-------------
                                          15728880   100% |   github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoToSpan /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:46
         0     0%  6.87%   15728880  7.06%                | github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoKeyToEncInvertedVal /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:38
                                          15728880   100% |   github.com/cockroachdb/cockroach/pkg/roachpb.Key.PrefixEnd /go/src/github.com/cockroachdb/cockroach/pkg/roachpb/data.go:188
----------------------------------------------------------+-------------
```

These allocations were largely avoidable. This commit removes some of
them entirely and reworks the code structure in order to amortize the
unavoidable allocations over the set of keys being encoded. The result
is a large reduction in allocations. On the same workload, allocations
under `geoKeyToEncInvertedVal` dropped from **27.52%** of the workload
to **2.23%** of the workload:

```
Type: alloc_objects
Time: Aug 21, 2020 at 5:04pm (UTC)
Active filters:
   focus=geoKeyToEncInvertedVal
Showing nodes accounting for 3632555, 2.23% of 162651628 total
----------------------------------------------------------+-------------
      flat  flat%   sum%        cum   cum%   calls calls% + context
----------------------------------------------------------+-------------
                                           2014518 55.46% |   github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoToSpan /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:53
                                           1618037 44.54% |   github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoToSpan /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:54
         0     0%     0%    3632555  2.23%                | github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoKeyToEncInvertedVal /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:44
                                           3632555   100% |   github.com/cockroachdb/cockroach/pkg/util/encoding.EncodeUvarintAscending /go/src/github.com/cockroachdb/cockroach/pkg/util/encoding/encoding.go:375
----------------------------------------------------------+-------------
```

When applied on top of #53181, this results in a **1.71%** speedup on
the following geospatial query:

```sql
SELECT Count(census.blkid), Count(subways.name)
FROM nyc_census_blocks AS census
JOIN nyc_subway_stations AS subways
ON ST_Intersects(subways.geom, census.geom);
```

```
name                                old ms    new ms    delta
Test/postgis_geometry_tutorial/nyc  136 ±12%  134 ±11%  -1.71%  (p=0.000 n=976+977)
```

In making this change, we also fix a bug where `geoindex.Key` (a uint64) was
being cast to a `tree.DInt` (an int64) during encoding. This could result in
overflow and could cause inverted key spans to be generated.

Co-authored-by: Yahor Yuzefovich <[email protected]>
Co-authored-by: Nathan VanBenschoten <[email protected]>
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.

3 participants