[postgis-users] Controlling PostGIS memory usage

Dan Gast dan at stormpulse.com
Wed Mar 26 12:48:24 PDT 2014


Hello,

I've found a way to crash PostgreSQL by running it out of memory, and
after looking at the documentation I'm unable to find tuning
parameters to stop it. Furthermore, I don't believe this query should
be using much memory at all.

I have a person table with 100k rows, and a store table with 100 rows
(schema below).

-- The following works ok:
SELECT COUNT(*) FROM person AS p, store AS s WHERE ST_Distance(p.geog,
s.geog) < 400000;

-- This will run the daemon out of memory:
SELECT COUNT(*) FROM person AS p, store AS s WHERE
ST_Intersects(ST_Buffer(s.geog, 400000), p.geog);

My fact-free suspicion is that ST_Buffer() is creating a GEOS object
for each "person" x "store", and these objects are not being released
after the result of the ST_Intersects(). If I add WHERE clause
conditions to reduce the check count (i.e. store.id < 6), memory usage
is more reasonable.

My questions:

1) Is this known, and if so, what should I read to understand what is
really going on?

2) I've been unsuccessful finding tunables to rein PostGIS-related
memory usage in. Can I control this? How?


Thanks,


Dan


Supporting notes:

Ubuntu 12.04, fully patched, or Ubuntu 14.04 recent but possibly not current.

PostgreSQL 9.3, PostGIS 2.1 out of apt.postgresql.org

Ubuntu 12.04: POSTGIS="2.1.1 r12113" GEOS="3.3.3-CAPI-1.7.4"
PROJ="Rel. 4.7.1, 23 September 2009" GDAL="GDAL 1.9.0, released
2011/12/29" LIBXML="2.7.8" LIBJSON="UNKNOWN" RASTER

Ubuntu 14.04: POSTGIS="2.1.1 r12113" GEOS="3.4.2-CAPI-1.8.2 r3921"
PROJ="Rel. 4.8.0, 6 March 2012" GDAL="GDAL 1.10.1, released
2013/08/26" LIBXML="2.9.1" LIBJSON="UNKNOWN" RASTER

SQL to build an empty DB up to test:

CREATE EXTENSION postgis;

CREATE TABLE person (
    id SERIAL,
    geog Geography(Point,4326)
);

CREATE TABLE store (
    id SERIAL,
    geog Geography(Point,4326)
);

CREATE FUNCTION people(numofthem integer) RETURNS void
    LANGUAGE plpgsql SECURITY DEFINER COST 10
    AS $$
BEGIN
FOR i IN 1 .. numofthem LOOP
INSERT INTO person (geog) VALUES (ST_MakePoint(RANDOM() * 360 - 180,
RANDOM() * 180 - 90));
END LOOP;
END;
$$;

CREATE FUNCTION stores(numofthem integer) RETURNS void
    LANGUAGE plpgsql SECURITY DEFINER COST 10
    AS $$
BEGIN
FOR i IN 1 .. numofthem LOOP
INSERT INTO store (geog) VALUES (ST_MakePoint(RANDOM() * 360 - 180,
RANDOM() * 180 - 90));
END LOOP;
END;
$$;

SELECT people(100000);
SELECT stores(100);


More information about the postgis-users mailing list