ST_Intersection медленный запрос


11

Я пытаюсь выполнить пересечение между двумя слоями:

  1. Слой полилинии, представляющий некоторые дороги (~ 5500 рядов)
  2. Многоугольный слой, представляющий буферы неправильной формы вокруг различных точек интереса (~ 47 000 строк)

В конечном итоге я пытаюсь обрезать полилинии для этих многочисленных (иногда перекрывающихся) буферов, а затем суммировать общую длину проезжей части, содержащейся в каждом буфере.

Проблема в том, что все работает медленно. Я не уверен, сколько времени это займет, но я просто прервал свой запрос после> 34 часов. Я надеюсь, что кто-то может либо указать, где я допустил какую-то ошибку в своем запросе SQL, либо указать мне лучший способ сделать это.

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;

У меня есть индекс GiST, созданный для исходной таблицы дорог, и (на всякий случай?) Создать индекс перед созданием второй таблицы.

План запросов от PGAdmin III выглядит следующим образом, хотя, боюсь, у меня нет особых навыков в его интерпретации:

"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)"

Эта операция просто обречена на несколько дней? В настоящее время я использую это на PostGIS for Windows, но теоретически я могу использовать больше оборудования для решения проблемы, поставив его на Amazon EC2. Однако я вижу, что запрос использует только одно ядро ​​за один раз (есть ли способ заставить его использовать больше?).


На чем работает Postgis? ОС и процессор могут быть фактором.
Mapperz

Привет Mapperz: ОС - Windows 7, CPU - Core 2 Duo, Память - 4 ГБ (Windows, 32-разрядная версия PGSQL / PostGIS)
Питер

Ответы:


6

Питер,

Какую версию PostGIS, GEOS и PostgreSQL вы используете?
сделать

ВЫБЕРИТЕ postgis_full_version (), version ();

Для этого было сделано множество улучшений между 1.4 и 1.5 и GEOS 3.2+.

Кроме того, сколько вершин у ваших полигонов?

Сделать

SELECT Max (ST_NPoints (the_geom)) Как maxp ОТ некоторого стабильного;

Чтобы понять ваш худший сценарий. Подобная медленная скорость часто вызывается геометрией, которая слишком мелкозерниста. В этом случае вы можете сначала упростить.

Также вы сделали оптимизацию для вашего файла postgresql.conf?


Привет, LR1234567: "POSTGIS =" 1.5.2 "GEOS =" 3.2.2-CAPI-1.6.2 "PROJ =" Rel. 4.6.1, 21 августа 2008 г. "LIBXML =" 2.7.6 "USE_STATS"; "PostgreSQL 9.0.3, скомпилирован в Visual C ++ build 1500, 32-bit" (сейчас выполняется другой запрос)
Питер

Запрос Max выполняется быстрее, чем я ожидал: maxp = 2030 Я подозреваю, что это довольно мелкозернистый?
Питер

1
2030 неплохо на самом деле. Возможно, у вас просто много полигонов, которые пересекаются. Обычно пересечение - это самая медленная часть. Попробуйте подсчитать, сколько записей на самом деле пересекается - это может быть огромно.
LR1234567

SELECT count (*) FROM public. "Roads" b, public. "Buffer1KM" z WHERE ST_Intersects (b.the_geom, z.the_geom);
LR1234567

1
910 978 огромен? Это хорошая вещь, когда вы начинаете использовать новую технологию - у меня нет нормативных ожиданий :-)
Питер

1

полезный ответ по обмену стека: /programming/1162206/why-is-postgresql-so-slow-on-windows

Настройка postgres: http://wiki.postgresql.org/wiki/Performance_Optimization

из опыта рекомендую ВАКУУМНЫЙ АНАЛИЗ


Спасибо, это звучит как хороший совет. Некоторые проблемы с Windows, такие как fork (), не должны быть проблемой, потому что у меня одно соединение, верно? Также запустили VACUUM ANALYZE. Я пока не копался в оптимизации производительности.
Питер

1
shared_buffers и work_mem обычно имеют наибольшее значение. Для shared_buffers вы немного более ограничены, насколько вы можете увеличить это в Windows, чем в Linux
LR1234567

shared_buffers уже был включен, но work_mem был выключен. Я добавил 1 ГБ рабочей памяти.
Питер

1

Бесстыдная заглушка :) Может помочь прочитать главу 8 и главу 9 нашей книги. Просто горячо от прессов. Мы рассмотрим много подобных вопросов в этих главах.

http://www.postgis.us/chapter_08

http://www.postgis.us/chapter_09


Ссылки не работают, это относится к PostGIS in Action или к поваренной книге PostGIS?
HeikkiVesanto

1
ах ты прав. Это были ссылки на первую редакцию PostGIS in Action, которая действовала тогда. Когда мы представили 2-е издание, нам пришлось изменить структуру ссылок. Старые ссылки, на которые ссылаются, теперь находятся здесь: postgis.us/chapters_edition_1
LR1234567,

0

Смотрите два совета для оптимизации пространственного запроса. Они работают очень хорошо для меня. http://kb.zillionics.com/optimize-spatial-query/


2
Этот ответ был бы лучше с некоторыми более подробными данными, такими как, как применить их в этом конкретном сценарии.
BradHards
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.