Come velocizzare le query per i database raster?


16

Ho un database raster in postgresql / postgis con queste colonne:

(ID, rast, data_of_data) .

'rast' è la colonna che ha file raster in formato WKT. Una query di esempio per trovare il valore DN di un punto nel sistema WGS84 (30.424, -1.66) e per il 2002-01-09 è la seguente:

SELECT 
     st_value(rast,(st_GeomFromText('POINT(30.424 -1.66)', 4326))) as val
FROM 
     my_table
WHERE
     date_of_data='2002-01-09'

Esiste un metodo (ad es. Indice spaziale) per accelerare questo tipo di query?


Forse potresti darci una mano fornendo ulteriori dettagli: quanti record ci sono in my_table? Quanto sono grandi i dati nella colonna raster? Quante date distinte hai in date_of_data?
dwurf,

Aggiungi a questo: qual è il SRID della colonna rast?
dwurf,

Risposte:


12

Questa è una domanda eccitante! Quanto è grande il raster che vuoi interrogare? WKTRaster è archiviato nel database come BLOB . Per trovare il valore in un punto specifico, da un angolo noto (x_0, y_0) gli indici di riga / colonna delle coordinate angolari (i, j) vengono calcolati utilizzando i passaggi (dx, dy) e la rotazione. Con (i, j) noto, la funzione ST_Value () può accedere ai dati effettivi con l'offset di byte corretto.

Ciò significa che il DB deve leggere in media almeno la metà del BLOB di dati quando risponde a una query per un punto (a seconda dell'implementazione può effettivamente leggere tutti i dati in qualsiasi momento). Immagino quindi che le prestazioni di WKTRaster soffrano quando i BLOB di dati diventano troppo grandi. La piastrellatura del set di dati dovrebbe accelerare le query. Dai un'occhiata a come vengono gestiti i dati SRTM (provenienti da blocchi di 6000x6000 pixel) in questo tutorial . In realtà affiancano i dati in pixel 50x50 davvero piccoli, il che è un chiaro suggerimento che la mia ipotesi potrebbe non essere troppo lontana dalla verità.

L'indicizzazione spaziale dei dati raster probabilmente indicizzerà semplicemente il rettangolo di selezione, il che non è un vero aiuto per il tuo problema.


1
La cosa della piastrellatura sembra essere la strada da percorrere - vedi questo link . Dovrai anche aggiungere un indice come questo: CREATE INDEX srtm_tiled_rast_gist_idx ON srtm_tiled USING GIST (ST_ConvexHull(rast));( fonte )
dwurf l'

4

Due aspetti che ho scoperto hanno velocizzato i miei calcoli raster PostGIS, usando valori interi nel raster e laddove possibile usando raster multibanda. In questo caso, il valore DN può essere memorizzato come numeri interi, se ciò non è già stato fatto?

L'altro pensiero (e non sono sicuro che sia rilevante qui) è quello di utilizzare raster multibanda. Ad esempio, se si stanno esaminando sezioni mensili di dati, ogni mese potrebbe essere un livello raster. Quindi è possibile recuperare più valori di un punto in diversi intervalli di tempo eseguendo una query sul raster a strati. Ho scoperto che questo approccio è molto più rapido rispetto all'interrogazione di raster separati.

Infine, quando carichi i tuoi dati c'è il -tflag per TILE_SIZE . È possibile esplorare se le dimensioni del riquadro che si sta utilizzando funzionano bene per la query.


I raster multibanda ti aiuteranno se hai bisogno di interrogare lo stesso valore di pixel per diversi mesi contemporaneamente (per rispettare l'esempio), ad esempio per analizzare le serie temporali. La query nella domanda recupera solo una data specifica. Se la data fosse contenuta in una banda, il DBMS dovrebbe leggere anche tutte le altre bande, anche se non sono interessanti per rispondere alla query. Questo probabilmente peggiorerebbe le prestazioni.
bhell,

Sono d'accordo - forse non ho sottolineato che è utile solo se sono necessari più valori contemporaneamente; Chiarirò questo.
djq,

3

A seconda della distribuzione dei dati, potresti ottenere degli ottimi speedups semplicemente indicizzando la date_of_datacolonna.

È possibile utilizzare la sintassi EXPLAIN ANALYZE per capire se gli indici vengono utilizzati o meno.


che tipo di indice? Potresti essere più specifico?
f.ashouri,

Basta un indice btree di serie: create index tbl_name_date_idx on tbl_name (date_of_data). Se hai molte date distinte, ciò ridurrà drasticamente la quantità di dati che PostGIS deve elaborare.
dwurf,

Grazie, ma non ha funzionato per la mia domanda.
f.ashouri,

Come non ha funzionato? Nessun evidente miglioramento delle prestazioni o altri problemi? Se hai una colonna di tabella che appare regolarmente in una WHEREclausola, dovresti sempre considerare di indicizzarla. In questo caso non sarà d'aiuto solo se hai molte date distinte (cioè un dominio di grande valore) ma anche se hai un gran numero di record nella tabella.
bhell,

La query utilizza l'indice? Puoi incollare l'output di explain analyze SELECT st_value(rast,(st_GeomFromText('POINT(30.424 -1.66)', 4326))) as val from my_table where date_of_data='2002-01-09'?
dwurf,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.