我使用了PostGIS以下最近邻查询:
SELECT g1.gid g2.gid FROM points as g1, polygons g2
WHERE g1.gid <> g2.gid
ORDER BY g1.gid, ST_Distance(g1.the_geom,g2.the_geom)
LIMIT k;
现在,我已经创建了the_geom指标以及GID列上两个表,这种查询花费更多的时间比其他空间查询涉及空间连接的B / W两个表。
有没有更好的方式来寻找K最近邻居? 我使用的PostGIS。
而且,它走的是一条不寻常的很长一段时间,尽管创建索引的几何列另一个查询是:
select g1.gid , g2.gid from polygons as g1 , polygons as g2
where st_area(g1.the_geom) > st_area(g2.the_geom) ;
我相信,这些查询的arent要点索引中受益,但是为什么呢?
鉴于此查询:
select a.polyid , sum(length(b.the_geom)) from polygon as a , roads as b
where st_intersects(a.the_geom , b.the_geom);
一段时间后,返回结果,尽管涉及“道路”表比多边形或分表大得多,并且还涉及更复杂的空间操作。
只是你的问题的一些想法:
st_distance以及st_area无法使用索引。 这是因为这两种功能不能被减少到这样的问题“是B内?” 或“做A和B的重叠?”。 更具体:GIST-指数只能在两个物体的边界框进行操作。
有关它的更多信息,你简直看在PostGIS的手册 ,其中规定与st_distance以及如何查询可以改善有更好的表现的例子。
然而,这并不能解决您的k最近邻问题。 对于这一点,现在我没有一个好主意,如何提高查询性能。 我看到的唯一的机会将被假设k个最近的邻居总是低于X米的距离。 然后,作为PostGIS的手动完成的,你可以使用类似的方法。
你的第二个查询可以加快一点。 目前,您计算在表1中经常每个对象的面积表有行 - 策略是第一个加入的数据,然后选择基于该功能。 你可以减少面积计算显著可以预先计算领域的计数:
WITH polygonareas AS (
SELECT gid, the_geom, st_area(the_geom) AS area
FROM polygons
)
SELECT g1.gid, g2.gid
FROM polygonareas as g1 , polygonareas as g2
WHERE g1.area > g2.area;
你的第三个查询可以用包围盒来显著优化:当两个物体的边界框不重叠,没有办法中的物件。 这使得一个给定的指标,因此巨大的性能增益的使用。
自2011年9月下旬 ,PostGIS中已经支持通过一个特殊的运算符(S)在ORDER BY子句中使用索引的近邻查询:
SELECT name, gid
FROM geonames
ORDER BY geom <-> st_setsrid(st_makepoint(-90,40),4326)
LIMIT 10;
...将返回10个对象,其geom
最接近-90,40
可伸缩的方式。 一些更多的细节(选项和注意事项),是在公告后和使用的< - >和的<#>运营商现在也官方PostGIS的2.0参考文件。 (两者之间的主要区别是, <->
比较形状重心和<#>
比较它们的边界-对分没有区别,其他形状选择什么是适合你的查询。)
你可能需要的是KNN指数而即将在PostGIS的2.x和9.1 PostgreSQL的希望:请参见http://blog.opengeo.org/tag/knn/
你可以用KNN指数做到这一点,横向连接。
SELECT v.gid, v2.gid,st_distance(v.the_geom, v2.the_geom)
FROM geonames v,
lateral(select *
from geonames v2
where v2.id<>v.id
ORDER BY v.the_geom <-> v2.the_geom LIMIT 10) v2
where v.gid in (...) - or other filtering condition
假设你有p指向和g的多边形,原始查询:
SELECT g1.gid, g2.gid FROM points as g1, polygons g2
WHERE g1.gid <> g2.gid
ORDER BY g1.gid, ST_Distance(g1.the_geom,g2.the_geom)
LIMIT k;
在返回k个最近的邻居在PXG集。 该查询可能会使用索引,但它仍然有权责令其整个PXG设置为找到的最小距离的k行。 你不是想要的是以下几点:
SELECT g1.gid,
(SELECT g2.gid FROM polygons g2
--prevents you from finding every nearest neighbour twice
WHERE g1.gid < g2.gid
--ORDER BY gid is erroneous if you want to limit by the distance
ORDER BY ST_Distance(g1.the_geom,g2.the_geom)
LIMIT k)
FROM points as g1;