문제

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() 특히 비용이 많이 듭니다. 과거에는 최적화했지만 PostGIS 함수를 생성하고 변수를 선언한 다음 결과를 할당하여 쿼리합니다. ST_GeomFromText 변수에.

다양한 매개 변수를 사용하여 쿼리에 대한 실행 계획을 확인해 보셨나요? 그러면 쿼리의 어느 부분에 시간이 걸리는지 확실히 알 수 있기 때문입니다.

나는 대부분의 실행 시간이 ST_DWithin() 그리고 ST_Distance(), ID 및 카테고리 열이 색인화되지 않은 경우에도 흥미로운 테이블 스캔을 수행하고 있을 수 있습니다.

다른 팁

@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개의 웨이포인트만 반환하는 것 같습니다.그러니 아마도 반환된 포인트에 적용되는 필터의 추가 비용에 대해서는 걱정하지 않아도 될 것 같습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top