Repository navigation
[improvement](geo) Decode constant shapes once in st_contains and other spatial relation functions - #70302
Open
guptashivam04 wants to merge 1 commit into
Open
[improvement](geo) Decode constant shapes once in st_contains and other spatial relation functions#70302guptashivam04 wants to merge 1 commit into
guptashivam04 wants to merge 1 commit into
Conversation
…er spatial relation functions
st_contains(st_polygon('POLYGON ((...))'), st_point(x, y)) decoded the constant polygon
again for every row. Decoding runs S2Polygon::IsValid(), which builds an S2 index over all
edges, so with a 12,864-vertex polygon each row cost about 1 ms and a query over 20k rows took
about 17 s.
- StRelationFunction (st_contains, st_within, st_intersects, st_touches, st_disjoint) now
decodes a constant argument once and keeps it in thread-local function state, keyed by its
encoded value, so it is reused across blocks.
- GeoPolygon::contains(point) converted every vertex to lat/lng on each call for the
point-on-edge check. The converted vertices are now cached on the polygon, and edges whose
bounding box (grown by the tolerance) does not contain the point are skipped before the exact
distance check. Results are unchanged.
Contributor
|
Thank you for your contribution to Apache Doris. Please clearly describe your PR:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Background
st_contains,st_within,st_intersects,st_touchesandst_disjointshare one BE implementation,StRelationFunction. Shapes travel between functions in their encoded form, so the relation function decodes both arguments before comparing them. Decoding a polygon also validates it (S2Polygon::IsValid()).What problem does this PR solve?
Issue Number: None
Related PR: None
PR Type: Performance
Problem Summary:
A filter like
ST_Contains(ST_Polygon('POLYGON ((...))'), ST_Point(lng, lat)) = 1decodes and validates the constant polygon again for every row. Validation builds an S2 index over all edges, so the cost per row grows with the vertex count. With a 12,864-vertex polygon that is about 1 ms per row: 20k candidate rows take about 17 s, while the scan itself takes about 20 ms. This PR decodes a constant argument once per scan thread and makes the point-on-edge check inGeoPolygon::containscheaper. Query results do not change.Details
Why it was slow:
GeoPolygon::decode→S2Polygon::IsValid→MutableS2ShapeIndexbuilding, once per row.GeoPolygon::contains. For every edge it converts both end vertices and the point toS2LatLng, which means trig calls, so 3 × vertices conversions per row.Optimization:
StRelationFunctiondecodes aColumnConstargument once. It keeps the decoded shape in a thread-localFunctionContextstate, keyed by the encoded bytes, so later blocks reuse it, and a different constant is decoded again.GeoPolygoncaches the lat/lng of its vertices on first use bycontains(point).project_distance(...) < TOLERANCEcheck on the same values as before, so the result is the same.StContainsStateis replaced by the new state struct.Results:
Small polygons (10 vertices) are unchanged, within noise.
Applicability and cost:
st_intersects,st_touchesandst_disjointagainst points get the decode saving but still loop over edges inpolygon_touch_point. That can be a follow-up.Testing
function_geo_st_contains_const_polygon: a constant polygon over many rows, as the first argument ofst_containsand the second ofst_within, plus an invalid constant.function_geo_st_contains_const_polygon_across_blocks: oneFunctionContextacross blocks whose constant changes.GeoTypesTest.polygon_contains_point_near_edge: points just inside and outside the 1e-6 edge tolerance, on outer and hole edges, with repeated calls on the same polygon.st_contains,st_within,st_intersects,st_touchesandst_disjoint, a constant multipolygon, a per-row (non-constant) polygon, and polygon-in-polygon.Release note
Spatial relation functions (
ST_Contains,ST_Within,ST_Intersects,ST_Touches,ST_Disjoint) with a constant polygon argument are much faster when the polygon has many vertices.Check List (For Author)