[PostGIS] #5828: Performace issue in ST_DFullyWithin
PostGIS
trac at osgeo.org
Sun Jan 5 19:32:04 PST 2025
#5828: Performace issue in ST_DFullyWithin
---------------------+---------------------------
Reporter: nbvfgh | Owner: pramsey
Type: defect | Status: new
Priority: blocker | Milestone: PostGIS 3.6.0
Component: postgis | Version: 3.5.x
Keywords: |
---------------------+---------------------------
**The premise of this issue is that ST_DFullyWithin(A, B, R) and
ST_MaxDistance(ST_ClosestPoint(A, B), B) <= R are equivalent.**
{{{
EXPLAIN ANALYZE SELECT ST_Contains(ST_Buffer(a, 2), a_translate)
FROM (SELECT ST_GeomFromText('POLYGON ((0 0, 0 1, 1 1, 1 0, 0 0))') AS a,
ST_GeomFromText('POLYGON ((1 1, 1 2, 2 2, 2 1, 1 1))') AS a_translate);
-- Execution Time: 0.017 ms
EXPLAIN ANALYZE SELECT ST_MaxDistance(ST_ClosestPoint(a, a_translate),
a_translate) <= 2
FROM (SELECT ST_GeomFromText('POLYGON ((0 0, 0 1, 1 1, 1 0, 0 0))') AS a,
ST_GeomFromText('POLYGON ((1 1, 1 2, 2 2, 2 1, 1 1))') AS a_translate);
-- Execution Time: 0.005 ms
}}}
We found that the running time of ST_DFullyWithin is several times that of
the equivalent query.
To eliminate the impact of randomness, we conducted the following
experiments:
{{{
DO $$
DECLARE
start_time TIMESTAMP;
end_time TIMESTAMP;
i INTEGER;
BEGIN
start_time := clock_timestamp();
FOR i IN 1..10000 LOOP
PERFORM ST_Contains(ST_Buffer(a, i), a_translate)
FROM (SELECT ST_GeomFromText('POLYGON ((0 0, 0 1, 1 1, 1 0, 0 0))') AS a,
ST_GeomFromText('POLYGON ((1 1, 1 2, 2 2, 2 1, 1 1))') AS a_translate);
END LOOP;
end_time := clock_timestamp();
RAISE NOTICE 'Total execution time for 10000 runs: %', end_time -
start_time;
END $$;
-- Total execution time for 10000 runs: 00:00:00.585733
DO $$
DECLARE
start_time TIMESTAMP;
end_time TIMESTAMP;
i INTEGER;
BEGIN
start_time := clock_timestamp();
FOR i IN 1..10000 LOOP
PERFORM ST_MaxDistance(ST_ClosestPoint(a, a_translate),
a_translate) <= i
FROM (SELECT ST_GeomFromText('POLYGON ((0 0, 0 1, 1 1, 1 0, 0 0))') AS a,
ST_GeomFromText('POLYGON ((1 1, 1 2, 2 2, 2 1, 1 1))') AS a_translate);
END LOOP;
end_time := clock_timestamp();
RAISE NOTICE 'Total execution time for 10000 runs: %', end_time -
start_time;
END $$;
-- Total execution time for 10000 runs: 00:00:00.016847
}}}
ST_MaxDistance(ST_ClosestPoint(A, B), B) <= R indeed runs more than almost
4 times faster than ST_DFullyWithin(A, B, R) in this case.
I know that the current implementation of ST_DFullyWithin(A, B, R) is
ST_Contains (ST_Buffer (A, R), B), if the equivalence relationship I
proposed holds, I believe there will be a significant improvement in the
performance of this function.
--
Ticket URL: <https://trac.osgeo.org/postgis/ticket/5828>
PostGIS <http://trac.osgeo.org/postgis/>
The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project.
More information about the postgis-tickets
mailing list