Consulta lenta ST_Intersection

11

Estou tentando fazer uma interseção entre duas camadas:

  1. Camada de polilinha representando algumas estradas (~ 5500 linhas)
  2. Camada de polígono representando buffers de forma irregular em torno de vários pontos de interesse (~ 47.000 linhas)

Por fim, o que estou tentando fazer é prender as polilinhas a esses muitos buffers (às vezes sobrepostos) e, em seguida, resumir a extensão total da estrada contida em cada buffer.

O problema é que as coisas estão lento. Não sei quanto tempo isso deve levar, mas acabei de cancelar minha consulta após> 34 horas. Espero que alguém possa apontar onde cometi algum erro com minha consulta SQL ou me indicar uma maneira melhor de fazer isso.

CREATE TABLE clip_roads AS

SELECT 
  ST_Intersection(b.the_geom, z.the_geom) AS clip_geom,
  b.*

FROM 
  public."roads" b, 
  public."buffer1KM" z

WHERE ST_Intersects(b.the_geom, z.the_geom);


CREATE INDEX "clip_roads_clip_geom_gist"
  ON "clip_roads"
  USING gist
  (clip_geom);



CREATE TABLE buffer1km_join AS

SELECT
  z.name, z.the_geom,
  sum(ST_Length(b.clip_geom)) AS sum_length_m

FROM
  public."clip_roads" b,
  public."buffer1KM" z

WHERE
  ST_Contains(z.the_geom, b.the_geom)

GROUP BY z.name, z.the_geom;

Eu tenho um índice GiST criado para a tabela de estradas original e (apenas por segurança?) Crie um índice antes de criar a segunda tabela.

O plano de consulta do PGAdmin III é assim, embora eu tenha medo de não ter muita habilidade para interpretá-lo:

"Nested Loop  (cost=0.00..29169.98 rows=35129 width=49364)"
"  Output: st_intersection(b.the_geom, z.the_geom), b.gid, b.geo_id, b.address_l, b.address_r, b.lf_name, b.lfn_id, b.lfn_name, b.lfn_type_c, b.lfn_type_d, b.lfn_dir_co, b.lfn_dir_de, b.lfn_desc, b.oe_flag_l, b.oe_flag_r, b.fcode_desc, b.fcode, b.fnode, b.tnode, b.metrd_num, b.lo_num_l, b.lo_n_suf_l, b.hi_num_l, b.hi_n_suf_l, b.lo_num_r, b.lo_n_suf_r, b.hi_num_r, b.hi_n_suf_r, b.juris_code, b.dir_code, b.dir_code_d, b.cp_type, b.length, b.the_geom"
"  Join Filter: _st_intersects(b.the_geom, z.the_geom)"
"  ->  Seq Scan on public."roads" b  (cost=0.00..306.72 rows=5472 width=918)"
"        Output: b.gid, b.geo_id, b.address_l, b.address_r, b.lf_name, b.lfn_id, b.lfn_name, b.lfn_type_c, b.lfn_type_d, b.lfn_dir_co, b.lfn_dir_de, b.lfn_desc, b.oe_flag_l, b.oe_flag_r, b.fcode_desc, b.fcode, b.fnode, b.tnode, b.metrd_num, b.lo_num_l, b.lo_n_suf_l, b.hi_num_l, b.hi_n_suf_l, b.lo_num_r, b.lo_n_suf_r, b.hi_num_r, b.hi_n_suf_r, b.juris_code, b.dir_code, b.dir_code_d, b.cp_type, b.length, b.the_geom"
"  ->  Index Scan using "buffer1KM_index_the_geom" on public."buffer1KM" z  (cost=0.00..3.41 rows=1 width=48446)"
"        Output: z.gid, z.objectid, z.facilityid, z.name, z.frombreak, z.tobreak, z.postal_cod, z.pc_area, z.ct_id, z.da_id, z.taz_id, z.edge_poly, z.cchs_0708, z.tts_06, z.the_geom"
"        Index Cond: (b.the_geom && z.the_geom)"

Esta operação está fadada a ser executada por vários dias? Atualmente, estou executando isso no PostGIS para Windows, mas, em teoria, eu poderia lançar mais hardware no problema, colocando-o no Amazon EC2. No entanto, vejo que a consulta está usando apenas um núcleo por vez (existe uma maneira de fazê-la usar mais?).

Pedro
fonte
Em que o Postgis está sendo executado? SO e processador podem ser um fator.
Mapperz
Oi Mapperz: OS é o Windows 7, CPU é Core 2 Duo, memória é de 4 GB (sendo o Windows, correndo de 32 bits PGSQL / PostGIS)
Peter

Respostas:

6

Pedro,

Qual versão do PostGIS, GEOS e PostgreSQL você está usando?
faça um

SELECT postgis_full_version (), versão ();

Muitas melhorias foram feitas entre 1.4 e 1.5 e o GEOS 3.2+ para esse tipo de coisa.

Também quantos vértices seus polígonos possuem?

Faça um

SELECT Max (ST_NPoints (the_geom)) Como maxp FROM algo;

Para ter uma idéia do seu pior cenário. A velocidade lenta como essa geralmente é causada por geometrias que são finalmente granuladas demais. Nesse caso, você pode querer simplificar primeiro.

Você também fez otimizações no seu arquivo postgresql.conf?

LR1234567
fonte
Olá LR1234567: "POSTGIS =" 1.5.2 "GEOS =" 3.2.2-CAPI-1.6.2 "PROJ =" Rel. 4.6.1, 21 de Agosto de 2008" LibXML = "2.7.6" USE_STATS ";" PostgreSQL 9.0.3, compilados pela Visual C ++ compilação 1500, 32 bits"(rodando a outra consulta agora)
Peter
A consulta Max foi executada mais rapidamente do que eu esperava: maxp = 2030 Eu suspeito que isso seja bastante refinado?
Peter
1
2.030 não é ruim, na verdade. Pode ser que você tenha muitos polígonos que se cruzam. Geralmente a interseção é a parte mais lenta. Tente contar quantos registros realmente se cruzam - pode ser enorme.
LR1234567
SELECT contagem (*) FROM público. "Estradas" b, público. "Buffer1KM" z WHERE ST_Intersects (b.the_geom, z.the_geom);
LR1234567
1
910.978 é enorme? Esta é a coisa agradável sobre a partir de uma nova tecnologia - Não tenho expectativas normativas :-)
Peter
1

resposta útil de troca de pilha: /programming/1162206/why-is-postgresql-so-slow-on-windows

Ajustando o postgres: http://wiki.postgresql.org/wiki/Performance_Optimization

por experiência recomendar ANÁLISE DE VÁCUO

Mapperz
fonte
Obrigado, isso parece um bom conselho. Alguns dos problemas do Windows, como a penalidade fork (), não devem ser um problema aqui, porque estou executando uma única conexão, certo? Além disso, execute o VACUUM ANALYZE. Ainda não fiz nenhuma otimização de desempenho.
Peter
1
shared_buffers e work_mem geralmente fazem a maior diferença. Para shared_buffers você está um pouco mais limitada quanto você pode até que no Windows que você está no linux
LR1234567
shared_buffers já estava ativado, mas work_mem estava desativado. Adicionei 1 GB de memória de trabalho agora.
Peter
1

Ficha descarada :) Pode ajudar a ler os capítulos 8 e 9 do nosso livro. Apenas quente fora das prensas. Abordamos muitas dessas questões nesses capítulos.

http://www.postgis.us/chapter_08

http://www.postgis.us/chapter_09

LR1234567
fonte
Os links estão quebrados. Refere-se ao PostGIS in Action ou ao PostGIS Cookbook?
precisa saber é o seguinte
1
ah você está certo. Esses eram links para a primeira edição do PostGIS in Action - que eram válidos na época. Quando lançamos a 2ª edição, tivemos que alterar a estrutura do link. Os links antigos aos quais se referem agora estão aqui: postgis.us/chapters_edition_1
LR1234567
0

Veja as duas dicas para otimizar a consulta espacial. Eles funcionam muito bem para mim. http://kb.zillionics.com/optimize-spatial-query/

zgle
fonte
2
Essa resposta seria melhor com mais detalhes, como aplicá-los nesse cenário específico.
precisa