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

Selectivity estimators for <@(spoint, scircle) and spoint_dwithin(spoint, spoint, float8) #80

Merged
merged 1 commit into from
Oct 20, 2023

Conversation

df7cb
Copy link
Contributor

@df7cb df7cb commented Oct 6, 2023

This implements restriction selectivity estimation for the <@ @> !<@ !@>
family of operators on spoint and scircle. The selectivity is estimated
to be (area of sphere circle) / (4 pi).

Queries like select * from sky where sky.star <@ scircle(const, radius)
will be able to properly estimate if using an index is appropriate
depending on the size of radius.

Secondly, a function spoint_dwithin(p1 spoint, p2 spoint, radius float8)
is added that effectively returns p1 <-> p2 <= radius. But other than
this two-operator expression, it has GIST index support so the optimizer
can rewrite it to either p1 <@ scircle(p2, radius) or p2 <@ scircle(p1, radius), i.e. it is symmetric in the first two arguments.

This allows efficient matching queries without the user having to encode
the join ordering in the query.

On PostgreSQL 10/11, the spoint_dwithin function is created, but without
the GIST support since that only appeared in PG12.

The file expected/selectivity_1.out is used on PG10/11; it has <@
flipped around to @> in some plans.

@esabol
Copy link
Contributor

esabol commented Oct 6, 2023

This is an awesome contribution! Thank you!

Makefile Show resolved Hide resolved
@df7cb
Copy link
Contributor Author

df7cb commented Oct 7, 2023 via email

Copy link
Contributor

@esabol esabol left a comment

Choose a reason for hiding this comment

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

Actually, could you make a couple minor tweaks to the documentation changes? Thanks!

doc/functions.sgm Outdated Show resolved Hide resolved
doc/functions.sgm Outdated Show resolved Hide resolved
src/point.c Outdated
float8 within = PG_GETARG_FLOAT8(2);
float8 dist = spoint_dist(p1, p2);

PG_RETURN_BOOL(dist <= within);
Copy link
Contributor

Choose a reason for hiding this comment

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

I guess, FPle should be used instead of direct comparison. pgSphere calculations are executed with EPSILON = 1E-9. When we compare two distances, all the numbers less than 1E-9 should be treated as zeroes, I think. There is the example: spoint_in_circle() function, where FPle is used. I would also propose to add some tests for this function, if it can be done.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ack, will change that (likely later, not now).

Copy link
Contributor

Choose a reason for hiding this comment

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

Sure, thank you! No hurry.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Implemented in 89dc41d.

src/pgs_util.h Show resolved Hide resolved
Makefile Show resolved Hide resolved
src/circle_sel.c Show resolved Hide resolved
src/circle_sel.c Show resolved Hide resolved
src/circle_sel.c Show resolved Hide resolved
pgs_circle_sel.sql.in Show resolved Hide resolved
src/circle_sel.c Show resolved Hide resolved
src/gist_support.c Show resolved Hide resolved
doc/functions.sgm Outdated Show resolved Hide resolved
@esabol
Copy link
Contributor

esabol commented Oct 18, 2023

In case anyone is interested in comparing selectivity estimators, similar efforts are in progress over in the q3c repo as well:

segasai/q3c#30
https://github.com/segasai/q3c/pull/35/files

@df7cb
Copy link
Contributor Author

df7cb commented Oct 18, 2023

Rebased.

Copy link
Contributor

@vitcpp vitcpp left a comment

Choose a reason for hiding this comment

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

Just one trivial change. Thank you!

src/point.c Outdated Show resolved Hide resolved
src/circle_sel.c Show resolved Hide resolved
This implements restriction selectivity estimation for the <@ @> !<@ !@>
family of operators on spoint and scircle. The selectivity is estimated
to be (area of sphere circle) / (4 pi).

Queries like `select * from sky where sky.star <@ scircle(const, radius)`
will be able to properly estimate if using an index is appropriate
depending on the size of radius.

Secondly, a function spoint_dwithin(p1 spoint, p2 spoint, radius float8)
is added that effectively returns `p1 <-> p2 <= radius`. But other than
this two-operator expression, it has GIST index support so the optimizer
can rewrite it to either `p1 <@ scircle(p2, radius)` or `p2 <@
scircle(p1, radius)`, i.e. it is symmetric in the first two arguments.

This allows efficient matching queries without the user having to encode
the join ordering in the query.

On PostgreSQL 10/11, the spoint_dwithin function is created, but without
the GIST support since that only appeared in PG12.

The file expected/selectivity_1.out is used on PG10/11; it has <@
flipped around to @> in some plans.
@vitcpp vitcpp merged commit 4dfc663 into postgrespro:master Oct 20, 2023
15 checks passed
@vitcpp
Copy link
Contributor

vitcpp commented Oct 20, 2023

@df7cb Thank you for the PR!

@df7cb
Copy link
Contributor Author

df7cb commented Oct 21, 2023

@vitcpp @esabol @Alena0704 thanks for the reviews!

@df7cb df7cb deleted the selectivity branch October 23, 2023 10:17
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.

4 participants