我对postgresql如何使用索引有疑问。我在Postgresql中使用Postgis启用数据库时,基于Geography Type Column的Gist Index Expression存在问题。
我有下表:
CREATE TABLE place
(
id serial NOT NULL,
name character varying(40) NOT NULL,
location geography(Point,4326),
CONSTRAINT place_pkey PRIMARY KEY (id )
)
然后我根据列“位置”创建了Gist Index Expression
CREATE INDEX place_buffer_5000m ON place
USING GIST (ST_BUFFER(location, 5000));
现在假设在表格路线中我有使用Linestring对象的列形状,我想检查该线穿过的5000m多边形(位置周围)。
我认为下面的查询应使用“place_buffer_5000m”索引,但不使用它。
SELECT place.name
FROM place, route
WHERE
route.id=1 AND
ST_CROSSES(route.shape::geometry, ST_BUFFER(place.location, 5000)::geometry))
表位有大约76000行。 Analyze and Vacuum在此表上运行,重新创建“place_buffer_5000m”索引,但在上述查询期间未使用索引。
当我在名为“area_5000m”(geograpthy类型)的表格中创建另一列并更新表格时,有什么好笑的?
UPDATE place SET area_5000m=ST_BUFFER(location, 5000)
然后为此列创建gist索引,如下所示:
CREATE INDEX place_area_5000m ON place USING GIST (area_5000m)
然后使用查询:
SELECT place.name
FROM place, route
WHERE
route.id=1 AND
ST_CROSSES(route.shape::geometry, place.area_5000m::geometry))
使用索引“place_area_5000m”。 问题是为什么不使用基于位置列计算的索引表达式?
答案 0 :(得分:1)
您是否尝试在“功能索引”中添加演员表? 这有助于确定数据类型。 它应该适用于几何,也可能适用于地理,如下所示:
CREATE INDEX place_buffer_5000m ON place
USING GIST(ST_BUFFER(location, 5000)::geometry);
答案 1 :(得分:0)
最终,您想知道5公里范围内的路线,这是一种非常简单和常见的查询类型。但是,您陷入了一个常见陷阱:不要使用ST_Buffer进行过滤!这很贵!
使用ST_DWithin,它将使用常规GiST索引(如果可用):
SELECT place.name
FROM place, route
WHERE route.id = 1 AND ST_DWithin(route.shape::geography, place.location, 5000);