Pregunta

En postgis, es el ST_GeomFromText llamar muy caro?Pregunto principalmente porque tengo una consulta llamada con frecuencia que intenta encontrar el punto más cercano a otro punto que coincida con algunos criterios, y que también esté dentro de una cierta distancia de ese otro punto, y de la forma en que lo escribí actualmente, está haciendo lo mismo. mismo ST_GeomFromText dos veces:

 $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");

¿Existe una mejor manera de reescribir esto?

Ligeramente OT:En la pantalla de vista previa, todos mis guiones bajos se representan como & # 9 5 ; - Espero que eso no aparezca así en la publicación.

¿Fue útil?

Solución

no creo ST_GeomFromText() es particularmente caro, aunque en el pasado he optimizado PostGIS consultas creando una función, declarando una variable y luego asignando el resultado de ST_GeomFromText a la variable.

¿Ha intentado verificar el plan de ejecución de su consulta con una variedad de parámetros diferentes porque eso debería darle una idea definitiva de qué partes de la consulta están tomando tiempo?

Supongo que la mayor parte del tiempo de ejecución estará en las llamadas a ST_DWithin() y ST_Distance(), aunque si las columnas id y categoría no están indexadas, es posible que se esté realizando un escaneo de tabla interesante.

Otros consejos

@Ubiguch parece que ST_DWithin utiliza el índice espacial, por lo que parece reducir la cantidad de puntos a consultar con bastante rapidez.

 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)

Sin el order by y el limit, parece que una consulta típica solo devuelve entre 5 y 10 puntos de referencia como máximo.Así que probablemente no debería preocuparme por el costo adicional del filtro que se aplica a los puntos devueltos.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top