Uma das coisas que torna desafiador o gerenciamento de dados geoespaciais é a enorme variedade de escalas que os dados geoespaciais cobrem: áreas tão grandes quanto um continente ou tão pequenas quanto um buraco feito pelo homem.

Os dados no banco de dados também abrangem uma ampla variedade, de pontos únicos, a polígonos com milhares de vértices. E o tamanho importa! Um objeto grande leva mais tempo para recuperá-lo e mais tempo para executar cálculos.

O arquivo de países da Natural Earth é um bom exemplo dessa variação. Carregue os dados no PostGIS e inspecione os tamanhos dos objetos usando SQL:

SELECT admin, ST_NPoints(the_geom), ST_MemSize(the_geom) 
FROM ne_10m_admin_0_countries 
ORDER BY ST_NPoints;
  • As Ilhas do Mar de Coral são representadas com um polígono de 4 pontos, apenas 112 bytes.
  • O Canadá é representado com um multi-polígono de 68159 pontos, 1 megabytes de tamanho!



Mais da metade (149) dos países da tabela é maior que o tamanho da página do banco de dados (8Kb), o que significa que eles levarão mais tempo para serem recuperados.

SELECT Count(*) 
FROM ne_10m_admin_0_countries 
WHERE ST_MemSize(the_geom) > 8192;

Podemos ver a sobrecarga envolvida no trabalho com grandes dados, forçando uma grande recuperação e poder computacional.

Carregue também a camada de locais populados do Natural Earth no PostGIS e execute uma junção espacial completa entre as duas tabelas:

SELECT Count(*)
FROM ne_10m_admin_0_countries countries 
JOIN ne_10m_populated_places_simple places 
ON ST_Contains(countries.the_geom, places.the_geom)

Embora a tabela de locais(7322) e a tabela de países(255) sejam muito pequenas, o cálculo ainda leva alguns segundos (que vai depender de computador pra computador).

Os objetos grandes causam várias ineficiências:

  • Áreas geograficamente grandes (como Canadá ou Rússia) têm grandes BBOXs, fazendo com que os índices não funcionem com a mesma eficiência na busca de pontos que não se enquadram nos países.
  • Objetos fisicamente grandes têm grandes listas de vértices, que levam muito tempo para passar pelo cálculo da função ST_Contains.

Como podemos acelerar o processo? Reduzindo os objetos grandes usando a função ST_Subdivide()!

Primeiro, é necessário gerar uma nova tabela de países subdivididos:

CREATE TABLE ne_10m_admin_0_countries_subdivided AS
SELECT ST_SubDivide(the_geom) AS the_geom, admin 
FROM ne_10m_admin_0_countries;

Agora temos os mesmos dados, mas nenhum objeto tem mais de 255 vértices (cerca de 4Kb) de tamanho!



Execute a união espacial novamente e veja a mudança:

SELECT Count(*)
FROM ne_10m_admin_0_countries_subdivided countries 
JOIN ne_10m_populated_places_simple places 
ON ST_Contains(countries.the_geom, places.the_geom)

No meu computador que foi executado o tempo de retorno foi de 0,5 segundos (60 vezes mais rápido), mesmo que a tabela de países agora tenha 8633 linhas. A subdivisão realizou duas coisas:

  • Agora, cada polígono cobre uma área menor; portanto, é menos provável que as pesquisas de índice obtenham pontos que não estão dentro do polígono.
  • Agora, cada polígono está abaixo do tamanho da página; portanto, a recuperação do disco será muito mais rápida.

Subdividir grandes coisas também pode tornar o desenho do mapa mais rápido, mas cuidado: depois que seus polígonos forem subdivididos, você terá que desativar os contornos do polígono para evitar mostrar os limites quadrados no mapa renderizado.

Esta post foi publicado originalmente no blog da CARTO.

Fonte: Clever Elephant Blog