如何使用索引强制Postgres?

时间:2017-07-18 09:05:43

标签: database postgresql performance postgis

我有以下查询,找到id

中的所有POLYGON(({points}))
SELECT id
FROM t
WHERE ST_DWithin('POLYGON(({points}))', ST_Point(latitude, longitude), 0);

查询很慢,因为它不使用(latitude, longitude)索引,必须为每对可能的点计算公式。

如何更改查询以强制Postgres使用(latitude, longitude)索引(我需​​要更改查询,因为我无法添加其他索引)?

我有以下索引:

"index_latitude_longitude" btree (latitude, longitude)

纬度,经度有double precision类型

我认为如果我们添加类似latitude <= ... and longitude <= ...的内容,Postgres会使用索引,我们该怎么办呢?

2 个答案:

答案 0 :(得分:0)

PostGIS的空间索引是BBOX。

使用&&运算符时,您正在使用BBOX,首先尝试

的性能
   SELECT id FROM t
   WHERE 'POLYGON(({points}))' &&  ST_Point(latitude, longitude);

ST_DWithin具有良好的性能,但参数0表示“交叉”,因此没有BBOX优化。

其他问题是缓存,因为你是构建几何:尝试

   CREATE TABLE kx_t AS 
     SELECT id, 
            'POLYGON(({points}))' as poly, 
            ST_Point(latitude, longitude) as pt  
     FROM t;

并使用kx_t测试您的查询,所以

   SELECT id FROM kx_t
   WHERE poly &&  pt;

WHERE ST_Intersects(poly,pt) ...

使用materialized view或此kx_t,您可以使用CREATE INDEX xxx ON kx_t USING GIST (the_geom)来提升效果。

PS:如果这里没有好的解决方案,请将您的问题复制到gis.stackexchange.com

答案 1 :(得分:0)

我更喜欢Postgres使用这样的索引:

SELECT id
FROM t, ( SELECT ST_GeomFromText('POLYGON(({points}))') as geom ) as polygon
WHERE longitude >= ST_XMIN(polygon.geom)
AND   longitude <= ST_XMAX(polygon.geom)
AND   latitude >= ST_YMIN(polygon.geom)
AND   latitude <= ST_YMAX(polygon.geom)
AND   ST_DWithin(polygon.geom, ST_Point(latitude, longitude), 0);