Desempenho PostGIS ST_Union

8

Estou tentando executar uma operação 'dissolver' no PostGIS usando o comando ST_Union.

A camada de entrada é reconhecidamente bastante grande e complexa. Por "grande", quero dizer 57.771 recursos, com número de vértices variando de 4 a 758.018 por recurso, com média de cerca de 86 vértices por recurso. Apenas cerca de 10 dos recursos têm> 10.000 vértices. Por "complexo", quero dizer que os polígonos têm muitos buracos, sobreposições confusas, ilhas etc. e que os polígonos grandes tendem a ter uma caixa delimitadora que cobre muitos dos polígonos menores, talvez tornando os índices menos úteis.

O problema é que a consulta é extremamente lenta a ponto de ser inutilizável. Li aqui o post de Paul em 2009 que me levou a acreditar que minha consulta ainda deveria ser bastante rápida. Estou usando o seguinte comando; estou fazendo algo flagrantemente errado ou ineficiente?

SELECT  ST_Union(f.geom) as geom, column1,column2,column3
FROM "inputlayer" As f 
GROUP BY column1,column2,column3

Edit: Estou usando:

POSTGIS="2.1.4 r12966" GEOS="3.3.3-CAPI-1.7.4" PROJ="Rel. 4.7.1, 23 September 2009" GDAL="GDAL 2.0.0dev, released 2014/04/16" LIBXML="2.7.8" LIBJSON="UNKNOWN" TOPOLOGY RASTER PostgreSQL 9.3.5 on x86_64-unknown-linux-gnu, compiled by gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3, 64-bit

A máquina na qual estou executando o servidor db é uma máquina virtual sem muita energia. Vou tentar a idéia SET work_mem = 50000 e ver como as coisas vão!

Darren Cope
fonte
Só para esclarecer, você deseja a união das geometrias para todas as combinações de coluna1, coluna2 e coluna3? Você pode definir grande, complexo e lento, e o que é explicado?
John Powell
1
John; sim, quero a união para todas as combinações das colunas 1,2 e 3. Não sei como quantificar 'grande' - mas é um número de polígonos muito complexos (muitos vértices) com sobreposições e ilhas confusas etc. terá que fazer uma pesquisa sobre 'explicar' antes que eu possa responder sua última pergunta!
precisa saber é o seguinte
O Explain pode não ser muito útil nesse caso, pois mede principalmente o tempo de busca do disco para realmente ler as linhas, com base nas estatísticas da tabela, índices etc. Ele não leva em consideração o tempo de execução de uma função como ST_Union, que depende da complexidade dos polígonos, o número de sobreposições, etc ..
John Powell
1
Edite a pergunta para adicionar detalhes.
Vince
1
Depende também da sua versão do GEOS. Melhores algoritmos de agregação foram introduzidos na versão 3.1.0.
Scro 23/01

Respostas:

3

Esse tipo de operação usa muita memória de trabalho, pelo que me lembro, portanto, você quer ter certeza de que não está nas configurações padrão, o que é bastante baixo;

Tente algo como

SET work_mem=50000;
Then run your query

Você pode querer brincar com essa configuração do workmem

Você também deseja despejar isso em uma tabela - e não na tela. Eu suponho que você já sabe

Outras coisas que você deseja verificar - que eu coloquei nos comentários, mas que repetirei aqui:

Há duas coisas que melhoraram a velocidade da união - a coisa em cascata que você apontou e, para a contagem de polígonos, o acúmulo mais rápido da matriz (que eu acho que veio no PostGIS 1.5 (pode ser que 1.4 não consiga se lembrar), o PostgreSQL 8.4 (a migration be 9.0 can não me lembro)). Também um GEOS mais novo não funcionará bem se você estiver executando o <PostGIS 1.4

Portanto, verificar as versões postgis e postgresql é importante

SELECT postgis_full_version() || ' ' || version();
LR1234567
fonte
Existe também ST_MemUnion. Usa menos memória, mais processadores: postgis.net/docs/ST_MemUnion.html
Scro
3
Essa função é bastante antiga. Eu acho que a nova implementação ST_Union realmente conserva a memória melhor do que essa função.
LR1234567
2

Mesmo antes de você executar ST_Union

ANALISE seu banco de dados para atualizar as estatísticas da consulta.

VACUUM seu banco de dados para limpar se você ainda não estiver executando o Autovacuum. Verifique suas configurações principais para garantir que estejam definidas com valores razoáveis.

shared_buffers should be 10% to 25% of available RAM
effective_cache_size should be 75% of available RAM 

Teste a alteração do work_mem : aumente para 8 MB, 32 MB, 256 MB, 1 GB. Isso faz diferença?

* 32 MB é o padrão

fonte: https://wiki.postgresql.org/wiki/Tuning_Your_PostgreSQL_Server

Mapperz
fonte
Obrigado. Eu apenas tentei ANALYZE, VACUUM e aumentando shared_buffers e effective_cache_size, e tive o mesmo problema. Vou continuar mexendo sempre que o tempo permitir.
Darren Cope
@DarrenCope algum progresso? Estou enfrentando o mesmo problema.
Michal Zimmermann
@zimmi; Infelizmente não :( Eu ainda estou onde eu estava antes Você está fazendo exatamente a mesma coisa Talvez compartilhar um exemplo e ver se existem semelhanças?
Darren Cope
1
@DarrenCope ST_Buffer (St_Collect (wkb_geometry), 0) parece ser muito mais rápido e atende às minhas necessidades. Isso pode ajudá-lo também.
Michal Zimmermann