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

opt: add index acceleration support for ~ and && bounding box operators #53023

Merged
merged 1 commit into from
Aug 20, 2020

Conversation

rytaft
Copy link
Collaborator

@rytaft rytaft commented Aug 19, 2020

This commit adds index acceleration support for the bounding box comparison
operators, ~ and &&. It maps ~ to Covers and && to Intersects.

Release note (performance improvement): The ~ and && geospatial bounding
box operations can now benefit from index acceleration if one of the
operands is an indexed geometry column.

@rytaft rytaft requested review from maddyblue, otan, sumeerbhola and a team August 19, 2020 13:27
@rytaft rytaft requested a review from a team as a code owner August 19, 2020 13:27
@cockroach-teamcity
Copy link
Member

This change is Reviewable

@otan
Copy link
Contributor

otan commented Aug 19, 2020

LGTM, but not fully read up on optimizer bits to point out anything major.
heads up you'll probably need to set the cluster setting for some of these in a rebase though.

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.

Reviewed 8 of 8 files at r1.
Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @mjibson, @otan, and @rytaft)


pkg/sql/logictest/testdata/logic_test/inverted_join_geospatial, line 223 at r1 (raw file):


query II
SELECT lk, rk FROM ltable JOIN rtable@geom_index ON rtable.geom && ltable.geom1

can you add some tests here and for inverted_filterer where one of these is cast to a box2d before doing && or ~.


pkg/sql/opt/invertedidx/geo.go, line 348 at r1 (raw file):

			t.Child(0).(opt.ScalarExpr), t.Child(1).(opt.ScalarExpr),
		}
		// Cast the arguments to type Geometry if needed (they may be type box2d).

same question as below about the cast failing.


pkg/sql/opt/invertedidx/geo.go, line 532 at r1 (raw file):

			t.Child(0).(opt.ScalarExpr), t.Child(1).(opt.ScalarExpr),
		}
		// Cast the arguments to type Geometry if needed (they may be type box2d).

what if the argument is not box2d? How is that cast error handled?


pkg/sql/opt/xform/testdata/rules/join, line 3491 at r1 (raw file):

FROM nyc_census_blocks AS c
JOIN nyc_neighborhoods@nyc_neighborhoods_geo_idx AS n
ON c.geom::box2d ~ n.geom

can you add a test with

 n.geom ~ c.geom::box2d

to show that it uses st_coveredby for the join.


pkg/sql/opt/xform/testdata/rules/select, line 2186 at r1 (raw file):


opt
SELECT k FROM g WHERE geom ~ 'BOX(1 2, 3 4)'::box2d

this is the CoveredBy case for the index yes?
I'm surprised that this isn't resulting in any intersection in the inverted expression below. It may be because these tests use a cell covering that is very coarse, so maybe the inner covering for this Box was a single cell. Can you tweak that to confirm that the right thing is happening?

Copy link
Collaborator Author

@rytaft rytaft left a comment

Choose a reason for hiding this comment

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

TFTRs!

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @mjibson, @otan, and @sumeerbhola)


pkg/sql/logictest/testdata/logic_test/inverted_join_geospatial, line 223 at r1 (raw file):

Previously, sumeerbhola wrote…

can you add some tests here and for inverted_filterer where one of these is cast to a box2d before doing && or ~.

Done.


pkg/sql/opt/invertedidx/geo.go, line 348 at r1 (raw file):

Previously, sumeerbhola wrote…

same question as below about the cast failing.

Done.


pkg/sql/opt/invertedidx/geo.go, line 532 at r1 (raw file):

Previously, sumeerbhola wrote…

what if the argument is not box2d? How is that cast error handled?

This works because the optimizer will not fold a cast if it would cause an error. If an argument is not either type geometry or box2d, that means this is not a bounding box operator, and therefore the checks inside constrainGeoIndexFromExpr will fail anyway.

However, I agree this is not obvious, and it seems like it only works by accident. I've cleaned it up a bit so hopefully it's clearer that it should work.


pkg/sql/opt/xform/testdata/rules/join, line 3491 at r1 (raw file):

Previously, sumeerbhola wrote…

can you add a test with

 n.geom ~ c.geom::box2d

to show that it uses st_coveredby for the join.

Done.


pkg/sql/opt/xform/testdata/rules/select, line 2186 at r1 (raw file):

Previously, sumeerbhola wrote…

this is the CoveredBy case for the index yes?
I'm surprised that this isn't resulting in any intersection in the inverted expression below. It may be because these tests use a cell covering that is very coarse, so maybe the inner covering for this Box was a single cell. Can you tweak that to confirm that the right thing is happening?

Done.

@mgartner
Copy link
Collaborator


pkg/sql/opt/invertedidx/geo.go, line 48 at r2 (raw file):

		return geoindex.Covers, true
	}
	if _, ok := expr.(*memo.OverlapsExpr); ok {

Would it make sense to have different memo expressions for the geo version of these operators? It might be safer in the case that normalization rules are added for *memo.RegMatchExpr or *memo.OverlapsExpr that don't apply to the geo versions.

I did something similar for the IS NULL operator here, FWIW: https://github.com/cockroachdb/cockroach/pull/48299/files#diff-15f17802e304627c3b80d68ac3394c4f

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 9 of 9 files at r2.
Reviewable status: :shipit: complete! 1 of 0 LGTMs obtained (waiting on @mjibson, @otan, @rytaft, and @sumeerbhola)

Copy link
Collaborator Author

@rytaft rytaft left a comment

Choose a reason for hiding this comment

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

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (and 1 stale) (waiting on @mjibson, @otan, and @sumeerbhola)


pkg/sql/opt/invertedidx/geo.go, line 48 at r2 (raw file):

Previously, mgartner (Marcus Gartner) wrote…

Would it make sense to have different memo expressions for the geo version of these operators? It might be safer in the case that normalization rules are added for *memo.RegMatchExpr or *memo.OverlapsExpr that don't apply to the geo versions.

I did something similar for the IS NULL operator here, FWIW: https://github.com/cockroachdb/cockroach/pull/48299/files#diff-15f17802e304627c3b80d68ac3394c4f

Good idea - Done.

Copy link
Collaborator

@mgartner mgartner left a comment

Choose a reason for hiding this comment

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

:lgtm:

Are changes in execbuilder/scalar.go required to turn *memo.BBoxCoversExpr and *memo.BBoxIntersectsExpr back into their original tree representation in the case that a query does not use an inverted index?

Reviewed 6 of 9 files at r2.
Reviewable status: :shipit: complete! 1 of 0 LGTMs obtained (and 1 stale) (waiting on @mgartner, @otan, @rytaft, and @sumeerbhola)


pkg/sql/opt/ops/scalar.opt, line 475 at r3 (raw file):


[Scalar, Bool, Comparison]
define BBoxCovers {

[nit] add a brief comment here explaining that these are ~ and && expressions for Geometry or Box2d types.


pkg/sql/opt/optbuilder/testdata/scalar, line 1382 at r3 (raw file):

overlaps [type=bool]
 ├── variable: "@1":1 [type=int[]]
 └── variable: "@2":2 [type=int[]]

[nit] add a test for when one child is a geometry/box2d and the other is not

This commit adds index acceleration support for the bounding box comparison
operators, ~ and &&. It maps ~ to Covers and && to Intersects.

Release note (performance improvement): The ~ and && geospatial bounding
box operations can now benefit from index acceleration if one of the
operands is an indexed geometry column.
Copy link
Collaborator Author

@rytaft rytaft left a comment

Choose a reason for hiding this comment

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

TFTRs!

Are changes in execbuilder/scalar.go required to turn *memo.BBoxCoversExpr and *memo.BBoxIntersectsExpr back into their original tree representation in the case that a query does not use an inverted index?

Nope, ComparisonOpReverseMap in operator.go does that.

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (and 2 stale) (waiting on @mgartner, @otan, and @sumeerbhola)


pkg/sql/opt/ops/scalar.opt, line 475 at r3 (raw file):

Previously, mgartner (Marcus Gartner) wrote…

[nit] add a brief comment here explaining that these are ~ and && expressions for Geometry or Box2d types.

Done.


pkg/sql/opt/optbuilder/testdata/scalar, line 1382 at r3 (raw file):

Previously, mgartner (Marcus Gartner) wrote…

[nit] add a test for when one child is a geometry/box2d and the other is not

Done.

Copy link
Collaborator

@mgartner mgartner left a comment

Choose a reason for hiding this comment

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

Nope, ComparisonOpReverseMap in operator.go does that.

Ahh, very good.

:lgtm_strong:

Reviewable status: :shipit: complete! 1 of 0 LGTMs obtained (and 1 stale) (waiting on @mgartner, @otan, and @sumeerbhola)

@rytaft
Copy link
Collaborator Author

rytaft commented Aug 20, 2020

bors r+

@craig
Copy link
Contributor

craig bot commented Aug 20, 2020

Build succeeded:

@craig craig bot merged commit 979127c into cockroachdb:master Aug 20, 2020
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.

6 participants