Comment accélérer les requêtes pour les bases de données raster?

16

J'ai une base de données raster dans postgresql / postgis avec ces colonnes:

(ID, rast, data_of_data) .

'rast' est la colonne qui contient des fichiers raster au format WKT. Un exemple de requête pour trouver la valeur DN d'un point dans le système WGS84 (30.424, -1.66) et pour le 2002-01-09 est le suivant:

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-t-il une méthode (par exemple, un index spatial) pour accélérer ce type de requêtes?

f.ashouri
la source
Peut-être pourriez-vous nous aider en fournissant plus de détails: Combien d’enregistrements sont dans ma_table? Quelle est la taille des données dans la colonne raster? Combien de dates distinctes avez-vous dans date_of_data?
dwurf
Ajoutez à cela: quel est le SRID de la colonne rast?
dwurf

Réponses:

12

Ceci est une question passionnante! Quelle est la taille du raster que vous souhaitez interroger? WKTRaster est stocké dans la base de données en tant que BLOB . Afin de trouver la valeur à un point spécifique, à partir d'une coordonnée d'angle connue (x_0, y_0), les indices de ligne / colonne (i, j) sont calculés en utilisant (dx, dy) des étapes et une rotation. Lorsque (i, j) est connu, la fonction ST_Value () peut accéder aux données réelles avec le décalage d'octet correct.

Cela signifie que la base de données doit lire en moyenne au moins la moitié du blob de données lorsqu'elle répond à une requête pour un point (selon l'implémentation, elle peut en fait lire toutes les données à tout moment). Je suppose donc que les performances de WKTRaster souffrent lorsque les BLOB de données deviennent trop volumineux. La mise en mosaïque de l'ensemble de données devrait accélérer les requêtes. Jetez un œil à la façon dont les données SRTM (venant en blocs de 6000x6000 pixels) sont traitées dans ce tutoriel . En fait, ils tuillent les données en très petits pixels 50x50, ce qui est un indice clair que ma supposition n'est peut-être pas trop loin de la vérité.

L'indexation spatiale des données raster va probablement simplement indexer le cadre de délimitation, ce qui n'est pas vraiment utile pour votre problème.

bhell
la source
1
Le carrelage semble être la voie à suivre - voir ce lien . Vous devrez également ajouter un index comme celui-ci: CREATE INDEX srtm_tiled_rast_gist_idx ON srtm_tiled USING GIST (ST_ConvexHull(rast));( source )
dwurf
4

Deux aspects que j'ai trouvés ont accéléré mes calculs de raster PostGIS, à savoir l'utilisation de valeurs entières dans le raster et l'utilisation de rasters multibandes dans la mesure du possible. Dans ce cas, la valeur DN peut-elle être stockée sous forme d'entiers, si ce n'est pas déjà fait?

L'autre pensée (et je ne suis pas certain que cela soit pertinent ici) est d'utiliser des rasters multi-bandes. Par exemple, si vous regardez des tranches de données mensuelles, chaque mois peut être une couche raster. Vous pouvez ensuite récupérer plusieurs valeurs d'un point à différentes tranches de temps en interrogeant le raster en couches. J'ai trouvé cette approche beaucoup plus rapide que l'interrogation de rasters distincts.

Enfin, lorsque vous chargez vos données, il y a l' -tindicateur pour TILE_SIZE . Vous pouvez découvrir si la taille de tuile que vous utilisez convient bien à votre requête.

djq
la source
Les rasters multibandes seront probablement utiles si vous devez interroger la même valeur de pixel pendant plusieurs mois en même temps (pour vous en tenir à votre exemple), par exemple pour analyser des séries chronologiques. La requête dans la question ne récupère qu'une seule date spécifique. Si la date était contenue dans une bande, le SGBD devrait également lire toutes les autres bandes, même si elles ne présentent aucun intérêt pour répondre à la requête. Cela détériorerait probablement les performances.
bhell
Je suis d'accord - je n'ai peut-être pas souligné qu'il n'est utile que si plusieurs valeurs sont nécessaires en même temps; Je vais clarifier cela.
djq
3

Selon la distribution de vos données, vous pouvez obtenir de très bonnes accélérations simplement en indexant la date_of_datacolonne.

Vous pouvez utiliser la syntaxe EXPLAIN ANALYZE pour déterminer si vos index sont utilisés ou non.

dwurf
la source
quel genre d'index? Pourriez-vous être plus précis?
f.ashouri
Juste un index standard btree: create index tbl_name_date_idx on tbl_name (date_of_data). Si vous avez plusieurs dates distinctes, cela réduira considérablement la quantité de données que PostGIS doit traiter.
dwurf
Merci, mais cela n'a pas fonctionné pour ma requête.
f.ashouri
Comment cela n'a-t-il pas fonctionné? Pas de gain de performances notable ou d'autres problèmes? Si vous avez une colonne de table qui apparaît régulièrement dans une WHEREclause, vous devez toujours envisager de l'indexer. Cela vous aidera non seulement dans ce cas si vous avez plusieurs dates distinctes (c'est-à-dire un domaine de grande valeur) mais aussi si vous avez un grand nombre d'enregistrements dans la table.
bhell
La requête utilise-t-elle l'index? Pouvez-vous coller la sortie 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