Question

En postgis, est-ce que ST_GeomFromText appeler très cher ?Je demande principalement parce que j'ai une requête fréquemment appelée qui tente de trouver le point le plus proche d'un autre point qui correspond à certains critères, et qui se trouve également à une certaine distance de cet autre point, et la façon dont je l'écris actuellement, cela fait le même ST_GeomFromText deux fois:

 $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-t-il une meilleure façon de réécrire cela ?

Légèrement OT :Dans l'écran d'aperçu, tous mes traits de soulignement sont rendus comme suit : & # 9 5 ; - J'espère que cela n'apparaîtra pas ainsi dans le message.

Était-ce utile?

La solution

je ne crois pas ST_GeomFromText() est particulièrement cher, même si dans le passé j'ai optimisé PostGIS requêtes en créant une fonction, en déclarant une variable puis en attribuant le résultat de ST_GeomFromText à la variable.

Avez-vous essayé de vérifier le plan d'exécution de votre requête avec une variété de paramètres différents, car cela devrait vous donner une idée précise des éléments de la requête qui prennent du temps ?

Je suppose que la majeure partie du temps d'exécution sera consacrée aux appels à ST_DWithin() et ST_Distance(), bien que si les colonnes id etcategory ne sont pas indexées, cela pourrait effectuer une analyse de table intéressante.

Autres conseils

@Ubiguch il semble que ST_DWithin utilise l'index spatial, ce qui semble réduire assez rapidement le nombre de points à interroger.

 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)

Sans le order by et le limit, il semble qu'une requête typique ne renvoie que 5 à 10 points de cheminement maximum.Je ne devrais donc probablement pas m'inquiéter du coût supplémentaire du filtre appliqué aux points renvoyés.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top