I am using postgis function ST_DWithin(geography gg1, geography gg2, double precision distance_meters), to find if a point is within a specified distance from a polygon. I am running tests to see how long does the query take and the explain shows that it is running sequential scan on tables instead of using BRIN or GIST indexes. Can someone suggest a way to optimise it.
Here are the tables -
table1(incident_geog) with polygons
CREATE TABLE public.incident_geog
(
incident_id integer NOT NULL DEFAULT nextval('incident_geog_incident_id_seq'::regclass),
incident_name character varying(20) COLLATE pg_catalog."default",
incident_span geography(Polygon,4326),
CONSTRAINT incident_geog_pkey PRIMARY KEY (incident_id)
)
CREATE INDEX incident_geog_gix
ON public.incident_geog USING gist
(incident_span)
table2 with points and distances(watchzones_geog)
CREATE TABLE public.watchzones_geog
(
id integer NOT NULL DEFAULT nextval('watchzones_geog_id_seq'::regclass),
date_created timestamp with time zone DEFAULT now(),
latitude numeric(10,7) DEFAULT NULL::numeric,
longitude numeric(10,7) DEFAULT NULL::numeric,
radius integer,
"position" geography(Point,4326),
CONSTRAINT watchzones_geog_pkey PRIMARY KEY (id)
)
CREATE INDEX watchzones_geog_gix
ON public.watchzones_geog USING gist
("position")
Sql with st_dwithin
explain select i.incident_id,wz.id from watchzones_geog wz, incident_geog i where ST_DWithin(position,incident_span,wz.radius * 1000);
Output of explain:
Nested Loop (cost=0.26..418436.69 rows=1 width=8)
-> Seq Scan on watchzones_geog wz (cost=0.00..13408.01 rows=600001 width=40)
-> Index Scan using incident_geog_gix on incident_geog i (cost=0.26..0.67 rows=1 width=292)
Index Cond: (incident_span && _st_expand(wz."position", ((wz.radius * 1000))::double precision))
Filter: ((wz."position" && _st_expand(incident_span, ((wz.radius * 1000))::double precision)) AND _st_dwithin(wz."position", incident_span, ((wz.radius * 1000))::double precision, true))
explain analyze
notexplain
and the query hasST_DWithin(position,incident_span,50)
, but the query plan seems to showST_DWithin(position,incident_span,(wz.radius * 1000)::double precision)
– Evan Carroll