ST_GeomFromText多少钱
时间:2020-03-05 18:45:30 来源:igfitidea点击:
在postgis中,ST_GeomFromText
调用是否非常昂贵?我之所以这么问,是因为我有一个经常调用的查询,该查询试图找到与符合条件的另一个点最接近的点,并且该点也位于该另一个点的一定距离之内,以及我目前编写它的方式,即相同的ST_GeomFromText
两次:
$findNearIDMatchStmt = $postconn->prepare( "SELECT internalid " . "FROM waypoint " . "WHERE id = ? AND " . " category = ? AND ". " (b.category in (1, 3) OR type like ?) AND ". " ST_DWithin(point, ST_GeomFromText(?," . SRID . " ),". SMALL_EPSILON . ") " . " ORDER BY ST_Distance(point, ST_GeomFromText(?,", SRID . " )) " . " LIMIT 1");
有没有更好的方法可以重写它?
略过OT:在预览屏幕中,我所有的下划线都被渲染为&9 5;
,我希望那不会在帖子中显示出来。
解决方案
回答
我不认为ST_GeomFromText()
特别昂贵,尽管过去我通过创建一个函数,声明一个变量然后将ST_GeomFromText
的结果分配给该变量来优化PostGIS
查询。
我们是否尝试过使用各种不同的参数检查查询的执行计划,因为这样可以使我们明确了解查询的哪些时间在花时间?
我猜大部分的执行时间都在对ST_DWithin()和ST_Distance()的调用中,尽管如果没有索引id和category列,那么它可能正在做一些有趣的表扫描。
回答
@Ubiguch
似乎" ST_DWithin"使用空间索引,因此似乎可以很快减少要查询的点数。
navaid=> explain select internalid from waypoint where id != 'KROC' AND ST_DWithin(point, ST_GeomFromText('POINT(-77.6723888888889 43.1188611111111)',4326), 0.05) order by st_distance(point, st_geomfromtext('POINT(-77.6723888888889 43.1188611111111)',4326)) limit 1; QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Limit (cost=8.37..8.38 rows=1 width=104) -> Sort (cost=8.37..8.38 rows=1 width=104) Sort Key: (st_distance(point, '0101000020E61000002FFE676B086B53C0847E44D7368F4540'::geometry)) -> Index Scan using waypoint_point_idx on waypoint (cost=0.00..8.36 rows=1 width=104) Index Cond: (point && '0103000020E61000000100000005000000000000C03B6E53C000000060D0884540000000C03B6E53C0000000409D95454000000020D56753C0000000409D95454000000020D56753C000000060D0884540000000C03B6E53C000000060D0884540'::geometry) Filter: (((id)::text <> 'KROC'::text) AND (point && '0103000020E61000000100000005000000000000C03B6E53C000000060D0884540000000C03B6E53C0000000409D95454000000020D56753C0000000409D95454000000020D56753C000000060D0884540000000C03B6E53C000000060D0884540'::geometry) AND ('0101000020E61000002FFE676B086B53C0847E44D7368F4540'::geometry && st_expand(point, 0.05::double precision)) AND (st_distance(point, '0101000020E61000002FFE676B086B53C0847E44D7368F4540'::geometry) < 0.05::double precision)) (6 rows)
没有order by
和limit
,看起来典型的查询最多只能返回5-10个航点。因此,我可能不必担心应用于返回点的过滤器的额外成本。