【发布时间】:2018-09-12 06:18:04
【问题描述】:
我正在使用 postgis 函数 ST_DWithin(geography gg1, geography gg2, double precision distance_meters) 来查找点是否在距多边形的指定距离内。我正在运行测试以查看查询需要多长时间,并且解释表明它正在对表运行顺序扫描,而不是使用 BRIN 或 GIST 索引。有人可以建议一种优化它的方法吗?
这是表格 -
table1(incident_geog) 与多边形
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(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")
带有 st_dwithin 的 Sql
explain select i.incident_id,wz.id from watchzones_geog wz, incident_geog i where ST_DWithin(position,incident_span,wz.radius * 1000);
解释的输出:
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而不是explain并且查询有ST_DWithin(position,incident_span,50),但是查询计划似乎显示ST_DWithin(position,incident_span,(wz.radius * 1000)::double precision) -
存在 seq 扫描,因为您没有过滤查询中的任何内容。您要求 DB 将一张表中的所有记录(因此您进行 seq 扫描)与距另一张表 50 米的记录(因此进行索引扫描)进行比较。
标签: postgresql postgis