¿Cómo acelerar las consultas para bases de datos ráster?

16

Tengo una base de datos ráster en postgresql / postgis con estas columnas:

(ID, rast, data_of_data) .

'rast' es la columna que tiene archivos ráster en formato WKT. Un ejemplo de consulta para encontrar el valor DN de un punto en el sistema WGS84 (30.424, -1.66) y para 2002-01-09 es el siguiente:

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

¿Existe un método (por ejemplo, índice espacial) para acelerar ese tipo de consultas?

f.ashouri
fuente
Quizás podría ayudarnos proporcionando más detalles: ¿Cuántos registros hay en my_table? ¿Qué tamaño tienen los datos en la columna ráster? ¿Cuántas fechas distintas tienes en date_of_data?
dwurf
Agregue a esto: ¿cuál es el SRID de la columna rast?
dwurf

Respuestas:

12

Esta es una pregunta emocionante! ¿Qué tan grande es el ráster que desea consultar? WKTRaster se almacena en la base de datos como un BLOB . Para encontrar el valor en un punto específico, a partir de una esquina (x_0, y_0) se calculan los índices de fila / columna de coordenadas (i, j) utilizando pasos (dx, dy) y rotación. Con (i, j) conocido, la función ST_Value () puede acceder a los datos reales en el desplazamiento de bytes correcto.

Esto significa que la base de datos tiene que leer en promedio al menos la mitad del blob de datos al responder una consulta para un punto (dependiendo de la implementación, en realidad puede leer todos los datos en todo momento). Por lo tanto, supongo que el rendimiento de WKTRaster se ve afectado cuando los BLOB de datos se hacen demasiado grandes. El mosaico del conjunto de datos debería acelerar las consultas. Eche un vistazo a cómo se manejan los datos SRTM (que vienen en fragmentos de 6000x6000 píxeles) en este tutorial . En realidad, agrupan los datos en píxeles realmente pequeños de 50x50, lo que es una clara pista de que mis suposiciones pueden no estar muy lejos de la verdad.

La indexación espacial de datos ráster probablemente solo indexará el cuadro delimitador, lo que no es una ayuda real para su problema.

bhell
fuente
1
El mosaico parece ser el camino a seguir: vea este enlace . También deberá agregar un índice como este: CREATE INDEX srtm_tiled_rast_gist_idx ON srtm_tiled USING GIST (ST_ConvexHull(rast));( fuente )
dwurf
4

Dos aspectos que encontré aceleraron mis cálculos de ráster PostGIS: usar valores enteros en el ráster y usar rásteres multibanda cuando sea posible. En este caso, ¿se puede almacenar el valor DN como enteros, si esto no se está haciendo ya?

El otro pensamiento (y no estoy seguro de que sea relevante aquí) es usar rásteres multibanda. Por ejemplo, si está viendo porciones mensuales de datos, cada mes podría ser una capa ráster. Luego puede recuperar múltiples valores de un punto en diferentes segmentos de tiempo al consultar el ráster en capas. Encontré que este enfoque es mucho más rápido que consultar rásteres separados.

Finalmente, cuando carga sus datos, aparece el -tindicador TILE_SIZE . Podría explorar si el tamaño de mosaico que está utilizando funciona bien para su consulta.

djq
fuente
Los rásteres multibanda probablemente ayudarán si necesita consultar el mismo valor de píxel durante varios meses al mismo tiempo (para seguir con su ejemplo), por ejemplo, para analizar series de tiempo. La consulta en la pregunta solo recupera una fecha específica. Si la fecha estuviera contenida en una banda, el DBMS también necesitaría leer todas las otras bandas, a pesar de que no son de interés para responder la consulta. Esto probablemente deterioraría el rendimiento.
Bhell
Estoy de acuerdo, tal vez no enfatice que solo es útil si se necesitan varios valores al mismo tiempo; Aclararé esto.
djq
3

Dependiendo de la distribución de sus datos, puede obtener algunas aceleraciones muy buenas simplemente indexando la date_of_datacolumna.

Puede usar la sintaxis EXPLAIN ANALYZE para determinar si sus índices se están utilizando o no.

dwurf
fuente
¿Qué tipo de índice? ¿Podría ser más específico?
f.ashouri
Sólo un índice árbolB estándar: create index tbl_name_date_idx on tbl_name (date_of_data). Si tiene muchas fechas distintas, esto reducirá drásticamente la cantidad de datos que PostGIS tiene que procesar.
dwurf
Gracias, pero no funcionó para mi consulta.
f.ashouri
¿Cómo no funcionó? ¿No hay aumento de rendimiento notable u otros problemas? Si tiene una columna de tabla que aparece regularmente en una WHEREcláusula, siempre debe considerar indexarla. No solo ayudará en este caso si tiene muchas fechas distintas (es decir, un dominio de gran valor) sino también si tiene una gran cantidad de registros en la tabla.
Bhell
¿La consulta está usando el índice? ¿Puedes pegar la salida de 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