2008-08-30 7 views
1

In Postgis, ist die 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 ist, der einigen Kriterien entspricht, und der auch in einer bestimmten Entfernung von diesem anderen Punkt liegt, und wie ich ihn gerade geschrieben habe gleich ST_GeomFromText zweimal:Wie teuer ist 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"); 

gibt es einen besseren Weg, dies neu zu schreiben?

Leicht OT: In der Vorschau werden alle meine Unterstriche als & # 9 5 ; gerendert - ich hoffe, dass das nicht in der Post angezeigt wird.

Antwort

1

Ich glaube nicht, ST_GeomFromText() ist besonders teuer, obwohl in der Vergangenheit habe ich Abfragen optimiert, indem Sie eine Funktion erstellen, eine Variable deklarieren und dann das Ergebnis ST_GeomFromText der Variablen zuweisen.

Haben Sie versucht, den Ausführungsplan für Ihre Abfrage mit einer Vielzahl von verschiedenen Parametern zu überprüfen, weil das Ihnen eine genaue Vorstellung davon geben sollte, welche Bits der Abfrage die Zeit brauchen?

Ich denke, die meiste Ausführungszeit wird in den Aufrufen zu ST_DWithin() und ST_Distance() sein, obwohl, wenn die ID-und Kategorie-Spalten nicht indiziert sind, könnte es einige interessante Tabelle Scannen.

1

@Ubiguch Es scheint, dass ST_DWithin den räumlichen Index verwendet, so dass die Anzahl der Punkte, die abgefragt werden sollen, ziemlich schnell verringert wird.

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 die order by und die limit, es sieht aus wie eine typische Abfrage 10.05 Wegpunkte max Rückkehr nur. Daher sollte ich mir wahrscheinlich keine Gedanken über die zusätzlichen Kosten des Filters machen, der auf die zurückgegebenen Punkte angewendet wird.

+1

+1 für die Verwendung von 'explain', um Zahlen statt Glauben zu erhalten. [Wie kann ich SQL-Abfragen mit psql Zeit] (http://dba.stackexchange.com/questions/3148/how-cani-i-time-sql-queries-using-psql) F & A könnte es wert sein, vor der vorzeitigen Optimierung zu erkunden spielt in. – jwd630