Como acelerar as consultas para bancos de dados rasterizados?

16

Eu tenho um banco de dados raster no postgresql / postgis com estas colunas:

(ID, rast, dados_de_dados) .

'rast' é a coluna que possui arquivos rasterizados no formato WKT. Uma consulta de exemplo para localizar o valor DN de um ponto no sistema WGS84 (30.424, -1.66) e para 09-01-2002 é a seguinte:

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 um método (por exemplo, índice espacial) para acelerar esse tipo de consulta?

f.ashouri
fonte
Talvez você possa nos ajudar fornecendo mais alguns detalhes: Quantos registros existem na minha_tabela? Qual o tamanho dos dados na coluna raster? Quantas datas distintas você tem em date_of_data?
Dwurf 11/12/12
Adicione a isso: qual é o SRID da coluna rast?
Dwurf 11/12/12

Respostas:

12

Esta é uma pergunta emocionante! Qual é o tamanho da varredura que você deseja consultar? O WKTRaster é armazenado no banco de dados como um BLOB . Para encontrar o valor em um ponto específico, a partir de um índice conhecido (x_0, y_0) de coordenadas de linha / coluna de canto (i, j) é calculado usando etapas (dx, dy) e rotação. Com (i, j) conhecido, a função ST_Value () pode acessar os dados reais no deslocamento de bytes correto.

Isso significa que o banco de dados precisa ler, em média, pelo menos metade do blob de dados ao responder a uma consulta de um ponto (dependendo da implementação, ele pode realmente ler todos os dados o tempo todo). Portanto, eu acho que o desempenho do WKTRaster sofre quando os BLOBs de dados ficam muito grandes. A colocação em bloco do conjunto de dados deve acelerar as consultas. Veja como os dados SRTM (que vêm em pedaços de 6000x6000 pixels) são tratados neste tutorial . Eles na verdade agrupam os dados em pixels 50x50 muito pequenos, o que é uma dica clara de que minhas suposições podem não estar muito longe da verdade.

A indexação espacial dos dados raster provavelmente indexará apenas a caixa delimitadora, o que não é uma ajuda real para o seu problema.

bhell
fonte
1
A coisa lado a lado parece ser o caminho a seguir - veja este link . Você também precisará adicionar um índice como este: CREATE INDEX srtm_tiled_rast_gist_idx ON srtm_tiled USING GIST (ST_ConvexHull(rast));( fonte )
dwurf
4

Dois aspectos que eu achei aceleraram meus cálculos de varredura do PostGIS, usando valores inteiros na varredura e usando rasters multibanda sempre que possível. Nesse caso, o valor DN pode ser armazenado como números inteiros, se isso ainda não estiver sendo feito?

O outro pensamento (e não tenho certeza de que seja relevante aqui) é usar raspadores de várias bandas. Por exemplo, se você estiver vendo fatias mensais de dados, cada mês poderá ser uma camada raster. Em seguida, você pode recuperar vários valores de um ponto em diferentes intervalos de tempo consultando a varredura em camadas. Achei essa abordagem muito mais rápida do que consultar rasters separados.

Finalmente, quando você carrega seus dados, há o -tsinalizador para TILE_SIZE . Você pode explorar se o tamanho do bloco que você está usando funciona bem para sua consulta.

djq
fonte
Rasters multibanda provavelmente ajudarão se você precisar consultar o mesmo valor de pixel por vários meses ao mesmo tempo (para ficar com o seu exemplo), por exemplo, para analisar séries temporais. A consulta na pergunta recupera apenas uma data específica. Se a data estivesse contida em uma banda, o DBMS também precisaria ler todas as outras bandas, mesmo que não tenham interesse em responder à consulta. Isso provavelmente deterioraria o desempenho.
bhell
Concordo - talvez não tenha enfatizado que isso só é útil se vários valores forem necessários ao mesmo tempo; Eu vou esclarecer isso.
DJQ
3

Dependendo da distribuição dos seus dados, você pode obter algumas acelerações muito boas apenas indexando a date_of_datacoluna.

Você pode usar a sintaxe EXPLAIN ANALYZE para descobrir se seus índices estão sendo usados ​​ou não.

dwurf
fonte
que tipo de índice? Você poderia ser mais específico?
f.ashouri
Apenas um índice btree padrão: create index tbl_name_date_idx on tbl_name (date_of_data). Se você tiver muitas datas distintas, isso reduzirá drasticamente a quantidade de dados que o PostGIS precisa processar.
Dwurf
Obrigado, mas não funcionou na minha consulta.
f.ashouri
Como isso não funcionou? Nenhum ganho de desempenho perceptível ou outros problemas? Se você possui uma coluna da tabela que aparece regularmente em uma WHEREcláusula, considere sempre indexá-la. Não só ajudará neste caso se você tiver muitas datas distintas (por exemplo, um domínio de grande valor), mas também se você tiver um grande número de registros na tabela.
bhell
A consulta está usando o índice? Você pode colar a saída 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 11/12/12