Frage

In Postgis ist das ST_GeomFromText Anruf sehr teuer?Ich frage hauptsächlich, weil ich eine häufig aufgerufene Abfrage habe, die versucht, den Punkt zu finden, der einem anderen Punkt am nächsten liegt, der bestimmte Kriterien erfüllt, und der sich auch in einer bestimmten Entfernung von diesem anderen Punkt befindet, und so wie ich es gerade geschrieben habe, tut es das Dasselbe ST_GeomFromText zweimal:

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

Gibt es eine bessere Möglichkeit, dies umzuschreiben?

Etwas OT:Im Vorschaubildschirm werden alle meine Unterstriche als gerendert & # 9 5 ; - Ich hoffe, dass das im Beitrag nicht so auffällt.

War es hilfreich?

Lösung

Ich glaube nicht ST_GeomFromText() ist besonders teuer, obwohl ich in der Vergangenheit optimiert habe PostGIS Abfragen durch Erstellen einer Funktion, Deklarieren einer Variablen und anschließendes Zuweisen des Ergebnisses ST_GeomFromText zur Variablen.

Haben Sie versucht, den Ausführungsplan für Ihre Abfrage mit verschiedenen Parametern zu überprüfen, denn das sollte Ihnen eine genaue Vorstellung davon geben, welche Teile der Abfrage die Zeit beanspruchen?

Ich gehe davon aus, dass die meiste Ausführungszeit in den Aufrufen von liegt ST_DWithin() Und ST_Distance(), obwohl, wenn die Spalten „id“ und „category“ nicht indiziert sind, möglicherweise ein interessanter Tabellenscan durchgeführt wird.

Andere Tipps

@Ubiguch Es scheint, dass ST_DWithin verwendet den räumlichen Index, sodass die Anzahl der abzufragenden Punkte ziemlich schnell reduziert werden kann.

 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)

Ohne das order by und das limit, sieht es so aus, als würde eine typische Abfrage nur maximal 5–10 Wegpunkte zurückgeben.Daher sollte ich mir wahrscheinlich keine Gedanken über die zusätzlichen Kosten machen, die durch den Filter entstehen, der auf die zurückgegebenen Punkte angewendet wird.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top