Because my comment about proximity searches seems to have caused confusion: the correct way to implement a high performance proximity filter to help with this specific scenario would be:
SELECT ST_Intersection(sl.geom, ST_Buffer(poi, 10000)) AS geom
FROM sea_level AS sl
CROSS JOIN LATERAL
ST_Transform(ST_SetSRID(ST_MakePoint(13.01667, 55.71667), 4326), 3006) AS poi
WHERE ST_DWithin(sl.geom, poi, 10000)
;
Here
ST_DWithin
quickly filters for all sl.geom
that would not fall inside the ST_Buffer
, and thus
- reduces the actual (and costly)
ST_Intersection
operation, on (less but still costly) ST_Buffer
'ed geometries, to only those sl.geom
that are relevant
- in effect does not include
NULL
values for non-intersecting features
- the
CROSS JOIN LATERAL
moves the point-of-interest creation (poi
) to a cache-able function value expression, mainly to avoid repeated calls
Without the need to intersect an ST_Buffer
, the filter would e.g. use a call to ST_Intersects
. In general, for where it's applicable, and functions interchangeable, the benefit of using ST_DWithin
is its algorithmic complexity, which may (dependent on geometry types) be lesser than that of a spatial overlap check except for the worst-case.
If you see any significant performance boost is questionable: the planner may neglect any indexes completely for a table that small, and a few thousand spatial overlap calculations on simple point buffers are fairly fast these days. But add two orders of magnitude to the row count, or more complex geometries, and the difference in execution times will be minutes to seconds.
ORDER BY
(except with a Primary Key column in theSELECT
), and the result set in your query includes all rows insea level
without a filter expression (e.g.WHERE
,JOIN
), so also those that don't have a spatial overlap (which areNULL
then). Hint: do not use a buffer for proximity filter - useST_DWithin
instead.