[postgis-users] Neighborhood Function using PL/PGSQL waaay to slow?
collin
collin at socrates.Berkeley.EDU
Mon Apr 19 19:18:12 PDT 2004
Folks,
I posted earlier regarding getting statistics for every point on their
neighboring points. Currently I am trying to find the lowest alititude
within a ~100 meter radius of each point. To do so, I wrote a PL/PGSQL
function (see below) which iterates through every row in a 10,000 row
table and updates each row with the lowest altitude within a bounding
box of 100meters.
-----------------------------------------------------------------------------------------------------
CREATE OR REPLACE FUNCTION collintest2() RETURNS integer AS '
DECLARE
thisrow RECORD;
zzmin double precision;
ztot integer := 0;
BEGIN
FOR thisrow IN SELECT * FROM test1 LOOP
SELECT INTO zzmin min(z) FROM test1 WHERE
the_geom &&
EXPAND(GeometryFromText(''POINT('' || thisrow.x || '' '' || thisrow.y ||
'' '' || thisrow.z ||'')'',32610),100);
EXECUTE ''UPDATE test1 SET zmin = '' || zzmin || '' WHERE x = '' ||
thisrow.x || '' AND y = '' || thisrow.y ;
ztot := ztot + 1;
END LOOP;
RETURN ztot;
END;
' LANGUAGE 'plpgsql';
--------------------------------------------------------------------------------------------------------
EXPLAIN ANALYZE SELECT collintest2();
QUERY PLAN
------------------------------------------------------------------------------------------------
Result (cost=0.00..0.01 rows=1 width=0) (actual
time=3318131.024..3318131.027 rows=1 loops=1)
Total runtime: 3318131.075 ms
This runs painfully slow, as you can see (331ms per row). Is there
another way to do this? I am new to pl/pgsql, though very familiar with
sql. How do I optimize? Use cursors? I built a gist index on the_geom,
but it doesn't make much of a difference.
Thanks in advance,
Collin Bode
GIS Informatics Researcher, UC Berkeley
The here is the schema for the table being operated on:
CREATE TABLE test1 (
the_geom geometry,
zmin double precision,
"time" double precision,
x double precision,
y double precision,
z double precision,
i double precision,
xf double precision,
yf double precision,
zf double precision,
if double precision
CONSTRAINT "$1" CHECK ((srid(the_geom) = 32610)),
CONSTRAINT "$2" CHECK (((geometrytype(the_geom) = 'POINT'::text) OR
(the_geom IS NULL)))
);
More information about the postgis-users
mailing list