Оптимізація дуже великої точки в полігоновому запиті


9

У мене є національний набір адресних точок (37 мільйонів) та набір даних багатокутника з обривів (2 мільйони) типу MultiPolygonZ, деякі полігони дуже складні, максимум ST_NPoints становить близько 200 000. Я намагаюся ідентифікувати за допомогою PostGIS (2.18), які точки адреси перебувають у багатокутнику затоплення, і записувати їх у нову таблицю з ідентифікатором адреси та деталями ризику затоплення. Я спробував з адресної точки зору (ST_Within), але потім змінив це положення, починаючи з точки зору заплави (ST_Contains), обґрунтовуючи це тим, що існують великі райони, які взагалі не мають ризику затоплення. Обидва набори даних було повторно відтворено на 4326, і обидві таблиці мають просторовий індекс. Мій запит нижче працює вже 3 дні і не показує ознак закінчення незабаром!

select a.id, f.risk_factor_1, f.risk_factor_2, f.risk_factor_3
into gb.addresses_with_flood_risk
from gb.flood_risk_areas f, gb.addresses a
where ST_Contains(f.the_geom, a.the_geom);

Чи існує більш оптимальний спосіб цього? Крім того, для тривалих запитів такого типу, що є найкращим способом моніторингу прогресу, окрім перегляду використання ресурсів та pg_stat_activity?


Мій оригінальний запит закінчився ОК, хоча і за 3 дні, і я пройшов іншу роботу, тому мені ніколи не присвячувався час на те, щоб спробувати рішення. Однак я тільки що завітав до цього і працюю над рекомендаціями, поки що добре. Я використав наступне:

  1. Створено 50-кілометрову сітку над Великобританією за допомогою запропонованого тут рішення ST_FishNet
  2. Встановіть SRID створеної сітки на British National Grid і побудуйте на ній просторовий індекс
  3. Обрізав мої дані про повені (MultiPolygon), використовуючи ST_Intersection та ST_Intersects (тут я отримав лише те, що мені довелося використовувати ST_Force_2D на геометрії, як shape2pgsql додав індекс Z
  4. Обрізав мої точкові дані за допомогою тієї ж сітки
  5. Створено індекси на рядок та колонки та просторовий індекс у кожній із таблиць

Я готовий запустити свій сценарій зараз, буду перебирати рядки та стовпці, що містять результати, до нової таблиці, поки я не охоплюю всю країну. Але я просто перевірив мої дані про повені, і деякі найбільш великі багатокутники, здається, були втрачені в перекладі! Це мій запит:

SELECT g.row, g.col, f.gid, f.objectid, f.prob_4band, ST_Intersection(ST_Force_2D(f.geom), g.geom) AS geom 
INTO rofrse.tmp_flood_risk_grid 
FROM rofrse.raw_flood_risk f, rofrse.gb_grid g
WHERE (ST_Intersects(ST_Force_2D(f.geom), g.geom));

Мої вихідні дані виглядають так:

Оригінальні дані про повені

Однак після відсікання це виглядає приблизно так:

Дані про затоплені повені

Це приклад "відсутнього" багатокутника:

"Відсутній" багатокутник


Я щойно зрозумів, що ми зустрілися на FOSS4G у Сеулі і розповіли про чудеса локатора HMS :-)
Джон Пауелл

Ви коли-небудь закінчували поділ і перемагали підхід? Чи можете ви оновити орієнтовний час за допомогою цього підходу?
andrew

Відповіді:


6

Перш ніж відповісти на ваше останнє запитання, дивіться цю публікаціюпро бажаність мати можливість контролювати хід запитів. Проблема є складною, і вона складеться в просторовому запиті, оскільки знання того, що 99% адрес вже було відскановано на стримування у багатокутнику затоплення, яке ви могли отримати з лічильника циклу в реалізації основної таблиці сканування, не обов'язково допоможіть, якщо кінцеві 1% адрес трапляться для перетину багатокутника, що займає повені, а більшість точок попереднього 99% перетинаються. Це одна з причин, чому EXPLAIN іноді не може бути корисним просторовим, оскільки він вказує на рядки, які будуть скановані, але, з очевидних причин, не враховує складність полігонів (а значить, велику частку часу виконання) будь-яких запитів типу перетину / перетину.

Друга проблема полягає в тому, що якщо ви подивитеся на щось подібне

EXPLAIN 
SELECT COUNT(a.id) 
FROM sometable a, someothertable b
WHERE ST_Intersects (a.geom, b.geom)

ви побачите щось на зразок, пропустивши безліч деталей:

_st_intersects(a.geom, b.geom)
   ->  Bitmap Index Scan on ix_spatial_index_name  (cost...rows...width...))
   Index Cond: (a.geom && geom)

Кінцева умова && - означає встановити обмежувальний прапорець перед тим, як зробити більш точний перетин фактичної геометрії. Це, очевидно, розумно і в основі роботи R-Trees. Однак, і я також працював над даними про повені у Великобританії в минулому, тому я знайомий зі структурою даних, якщо (Багато) полігони дуже великі - ця проблема особливо гостра, якщо річка протікає з, скажімо, 45 градусів - ви отримуєте величезні обмежувальні коробки, які можуть змусити перевірити величезну кількість потенційних перехресть на дуже складних багатокутниках.

Єдине рішення, яке мені вдалося придумати для "мого запиту працює 3 дні, і я не знаю, чи є у нас на 1% чи 99%" проблема - це використовувати своєрідний поділ і перемогти для манекенів підхід, під яким я маю на увазі, розбийте вашу область на менші шматки та запустіть їх окремо, або в циклі в plpgsql, або явно в консолі. Це має перевагу розрізання складних багатокутників на частини, а це означає, що подальша точка перевірки полігонів працює над меншими багатокутниками, а обмежувальні коробки полігонів значно менші.

Мені вдалося за один день запускати запити, розбивши Великобританію на 50 км на 50 км, після вбивства запиту, який вже протягом тижня працює по всій Великобританії. Вбік, я сподіваюсь, що ваш запит вище - СТВОРИТИ ТАБЛИЦЬ або ОНОВЛЕННЯ, а не лише ВИБІР. Коли ви оновлюєте одну таблицю, адреси, засновані на знаходженні в полігоні потопу, вам доведеться сканувати всю оновлену таблицю, адреси все одно, тому фактично наявність просторового індексу на ній зовсім не допомагає.

EDIT: Виходячи з того, що зображення вартує тисячі слів, ось зображення деяких даних про повені у Великобританії. Є один дуже великий багатокутник, обмежувальний ящик якого охоплює всю цю площу, тому легко зрозуміти, як, наприклад, спочатку перетинаючи багатоводковий полігон червоною сіткою, квадрат у південно-західному куті раптом лише перевірятиметься проти крихітного підмножини багатокутника.

введіть тут опис зображення


Вітаю, Джон і дуже дякую за вичерпну відповідь, я буду дотримуватися вашої рекомендації щодо підходу до сітки, звучить як дуже розумна пропозиція, я не хочу дуже спрощуватись і втрачати точність. Я буду орієнтуватися на один блок, а потім працювати паралельно, набагато простіше в ці дні з хмарою! Ще раз дякую
Марк Варлі

Привіт Марк, не хвилюйтеся, будь ласка, подумайте про прийняття відповіді, якщо відчуєте, що це допомогло. Це допомагає зберегти сайт в чистоті, питання без прийнятих відповідей - одна з показників, на які дивляться сайти обміну стеками.
Джон Пауелл

Гаразд все готово, це моя перша публікація тут, я зазвичай знаходжу відповідь з детальних тем та корисних відповідей. Цей запит, нарешті, закінчився сьогодні вранці, приблизно через 3 дні, що не так вже й погано, але сьогодні ми будемо слідувати вашим порадам і розбивати його на шматки для кращої роботи. Ще раз дякую за вашу допомогу, Джон і, можливо, побачимось у Бонні в серпні!
Марк Варлі

Я додав фотографію, хоча розумію, що у вас є зображення: D, це може допомогти іншим візуалізувати те, про що я. Так, я майже напевно їду до Foss4G UK, і буду думати про Бонна.
Джон Пауелл
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.