Domanda

In postgis, è il ST_GeomFromText chiamare molto caro?Lo chiedo soprattutto perché ho una query chiamata di frequente che tenta di trovare il punto più vicino a un altro punto che corrisponde ad alcuni criteri e che si trova anche entro una certa distanza da quell'altro punto e, nel modo in cui l'ho scritto attualmente, sta facendo il Stesso ST_GeomFromText due volte:

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

C'è un modo migliore per riscriverlo?

Leggermente OT:Nella schermata di anteprima, tutti i miei caratteri di sottolineatura vengono visualizzati come & # 9 5 ; - Spero che non venga visualizzato in questo modo nel post.

È stato utile?

Soluzione

Non ci credo ST_GeomFromText() è particolarmente costoso, anche se in passato l'ho ottimizzato PostGIS query creando una funzione, dichiarando una variabile e quindi assegnando il risultato di ST_GeomFromText alla variabile.

Hai provato a controllare il piano di esecuzione della tua query con una varietà di parametri diversi perché questo dovrebbe darti un'idea precisa di quali parti della query richiedono tempo?

Immagino che la maggior parte del tempo di esecuzione riguarderà le chiamate a ST_DWithin() E ST_Distance(), anche se se le colonne ID e categoria non sono indicizzate, potrebbe essere eseguita un'interessante scansione della tabella.

Altri suggerimenti

@Ubiguch sembra che ST_DWithin utilizza l'indice spaziale, quindi sembra ridurre il numero di punti da interrogare abbastanza rapidamente.

 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)

Senza il order by e il limit, sembra che una query tipica restituisca solo 5-10 waypoint al massimo.Quindi probabilmente non dovrei preoccuparmi del costo aggiuntivo del filtro applicato ai punti restituiti.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top