Postgresql 基于地理类型列问题的GIST索引表达

Postgresql 基于地理类型列问题的GIST索引表达,postgresql,indexing,postgis,Postgresql,Indexing,Postgis,我对postgresql如何使用索引有疑问。在支持Postgis的Postgresql数据库中,基于地理类型列的Gist索引表达式存在问题 我有下表: CREATE TABLE place ( id serial NOT NULL, name character varying(40) NOT NULL, location geography(Point,4326), CONSTRAINT place_pkey PRIMARY KEY (id ) ) 然后,我根据“位置”列创建

我对postgresql如何使用索引有疑问。在支持Postgis的Postgresql数据库中,基于地理类型列的Gist索引表达式存在问题

我有下表:

CREATE TABLE place
(
  id serial NOT NULL,
  name character varying(40) NOT NULL,
  location geography(Point,4326),
  CONSTRAINT place_pkey PRIMARY KEY (id )
)
然后,我根据“位置”列创建了Gist索引表达式

现在假设在表route中,我有一个带有Linestring对象的列形状,我想检查该线穿过的5000m多边形(在该位置周围)

我认为下面的查询应该使用“place\u buffer\u 5000m”索引,但不使用它

SELECT place.name
FROM place, route
WHERE
  route.id=1 AND
  ST_CROSSES(route.shape::geometry, ST_BUFFER(place.location, 5000)::geometry))
桌位大约有76000行。通过重新创建“place_buffer_5000m”索引在此表上运行Analyze and Vacuum,但在上述查询期间未使用该索引

当我在table place中创建另一个名为“area_5000m”(Geography类型)的列并更新该表时,有趣的是:

UPDATE place SET area_5000m=ST_BUFFER(location, 5000)
然后为该列创建要点索引,如下所示:

CREATE INDEX place_area_5000m ON place USING GIST (area_5000m)
CREATE INDEX place_buffer_5000m ON place
USING GIST(ST_BUFFER(location, 5000)::geometry);
然后使用查询:

SELECT place.name
FROM place, route
WHERE
  route.id=1 AND
  ST_CROSSES(route.shape::geometry, place.area_5000m::geometry))
使用“地点面积5000m”索引。
问题是为什么不使用基于位置列计算的索引表达式?

是否尝试将强制转换添加到“功能索引”中? 这有助于确定数据类型。 它应该适用于几何,也可能适用于地理,如:

CREATE INDEX place_area_5000m ON place USING GIST (area_5000m)
CREATE INDEX place_buffer_5000m ON place
USING GIST(ST_BUFFER(location, 5000)::geometry);

最后,您需要知道距离地点5公里以内的路线,这是一种非常简单和常见的查询类型。然而,您陷入了一个常见的陷阱:不要使用ST_缓冲区进行过滤!太贵了

使用,将使用常规的GiST索引(如果可用):


我从未见过在索引中成功使用st_buffer(),这似乎表明postGIS正在努力在索引中使用函数。place_area_5000m索引更有意义,因为您是在集合字段而不是函数(派生)字段上建立索引。它的行为似乎和预期的一样,但我可能已经离开了……我真的很好奇以前是否有人成功地通过GIS功能进行索引。迈克,谢谢你的回复。我知道。这不是解决我的问题的办法。有些地方在某些情况下需要小于5000米的缓冲区,在某些特殊情况下需要更大的缓冲区。对于ST_DWithin,我沿着路线只有一个值(与路线的距离)。我知道我没有提到这一点,但问题是为什么postgres没有使用基于表达式的gist索引。明白了:当ST_DWithin的第三个参数(距离)可变时,索引的使用就丢失了。有趣。