Более

Обратное геокодирование планеты Postgres OSM


Я создаю функцию для обратного геокодирования в Postgres, используя функции PostGIS. На данный момент я смог очистить все данные, которые были бесполезны для меня (реки, здания и т. Д.). У меня есть 3 стола (world_osm_roads - в witch - все дороги, world_osm_places - в witch - все города и world_osm_countrys - в witch - все страны). Теперь я могу получить запись с указанием страны, города и дороги менее чем за 10 мс, но для веб-службы все еще слишком медленно обрабатывать несколько запросов в секунду. Вот функция

СОЗДАТЬ ИЛИ ЗАМЕНИТЬ ФУНКЦИЮ public.nearest_neighbor_way_v1 (lat float8, lon float8) ВОЗВРАЩАЕТ УСТАНОВКУ nn_road AS $ BODY $ DECLARE gps_point geometry; НАЧНИТЕ, ЕСЛИ $ 1 НЕ ПУСТОЙ И $ 2 НЕ ПУСТОЙ ТОГДА gps_point: = st_geomfromtext ('POINT (' || $ 2 || "|| $ 1 || ')', 4326); ВОЗВРАТ ВЫБОР ЗАПРОСА iso2 :: характерное изменение, имя_места: : изменение символа, идентификатор дороги, имя_ дороги :: изменение символа, тип дороги :: изменение символа, max_speed_kmh, расстояние, ST_x (ближайшая_точка) :: numeric (10,7), ST_Y (ближайшая_точка) :: numeric (10,7) FROM (SELECT wop.name place_name, road_id, road_name, max_speed_kmh, closest_point, distance, road_type FROM (SELECT road_id, road_name, road_type, max_speed_kmh, st_closestpoint (way, gps_point) closest_point, st_distance (gps_point, way) distance, way FROSM , 0.0003) && way AND st_dwithin (gps_point, way, 0.0003) ORDER BY Distance LIMIT 1) a, (SELECT name, way FROM world_osm_places WHERE st_expand (gps_point, 0.05) && way) wop WHERE st_contains (wop.way, closest_point) ORDER ПО ST_Perimeter (wop.way) LIMIT 1) c, (SELECT iso2, geom FROM world_osm_countrys WHERE st_expand (gps_point, 0.05) && ge om) wocy WHERE st_contains (wocy.geom, closest_point) LIMIT 1; КОНЕЦ ЕСЛИ; ВОЗВРАЩЕНИЕ; END $ BODY $ LANGUAGE plpgsql VOLATILE;

Есть ли какие-нибудь предложения, как сделать мою работу быстрее?

РЕДАКТИРОВАТЬ:

В виде Якуб Кания предложил позвонить вОБЪЯСНИТЬ АНАЛИЗи получил следующие результаты:

«Предел (стоимость = 17,82… 26,13 рядов = 1 ширина = 94) (фактическое время = 0,141… 0,141 рядов = 0 петель = 1)» «-> Вложенный цикл (стоимость = 17,82… 26,13 рядов = 1 ширина = 94) (фактическое time = 0.140… 0.140 rows = 0 loops = 1) "" Фильтр объединения: ((world_osm_countrys.geom && (st_closestpoint (world_osm_roads.way, '0101000020E6100000772D211FF45F53C0A91611C5E42D4540' :: geometry)) (world_stoads_contains_gеометрия)) (world_stoads_contains_contains_game)) .way, '0101000020E6100000772D211FF45F53C0A91611C5E42D4540' :: geometry)))) "" -> Limit (стоимость = 17,68… 17,68 строк = 1 ширина = 5664) (фактическое время = 0,139… 0,139 строк = 0 петель = 1) "" -> Сортировка (стоимость = 17,68… 17,68 строк = 1 ширина = 5664) (фактическое время = 0,139… 0,139 строк = 0 циклов = 1) «« Ключ сортировки: (st_perimeter (world_osm_places.way)) »« Метод сортировки: быстрая сортировка Память: 25 КБ » «-> Вложенный цикл (стоимость = 9,37… 17,67 строк = 1 ширина = 5664) (фактическое время = 0,130… 0,130 строк = 0 циклов = 1)» «Фильтр объединения: ((world_osm_places.way && (st_closestpoint (world_osm_roads.way, '0101000020E6100000772D211FF45F53C0A91611C5E42D4540' :: геометрия))) И _st_ содержит (world_osm_places.way, (st_closestpoint (world_osm_roads.way, '0101000020E6100000772D211FF45F53C0A91611C5E42D4540' :: geometry))) "" -> Limit (стоимость = 9,08… 9,09 строк = 1 ширина = 245) (фактическое время = 0,129 0 циклов = 1) «» -> Сортировка (стоимость = 9,08… 9,09 строк = 1 ширина = 245) (фактическое время = 0,129… 0,129 строк = 0 циклов = 1) «» Ключ сортировки: (st_distance ('0101000020E6100000772D211FF45F53C0A91611C5E42D4540' :: geometry, world_osm_roads.way)) "" Метод сортировки: quicksort Память: 25kB "" -> Сканирование индекса с использованием routes_index на world_osm_roads (стоимость = 0,55… 9,07 строк = 1 ширина = 245) (фактическое время = 0,122… 0,122 строк = 0 циклов = 1)»" Индекс Cond: (( '0103000020E610000001000000050000008CB96B09F95F53C07EFE7BF0DA2D45408CB96B09F95F53C0D42EA699EE2D454062A1D634EF5F53C0D42EA699EE2D454062A1D634EF5F53C07EFE7BF0DA2D45408CB96B09F95F53C07EFE7BF0DA2D4540' :: геометрия && способом) И (путь && «0103000020E610000001000000050000008CB96B09F95F53C07EFE7BF0DA2D45408CB96B09F95F53C0D42EA699EE2D454062A1D634EF5F53C0D42EA699EE2D454062A1D634EF5F53C07EFE7BF0DA2D45 408CB96B09F95F53C07EFE7BF0DA2D4540' :: геометрия))»" Фильтр: (( '0101000020E6100000772D211FF45F53C0A91611C5E42D4540' :: геометрия && st_expand (путь, +0,000299999999999999974 :: двойной точности)) И _st_dwithin ( '0101000020E6100000772D211FF45F53C0A91611C5E42D4540' :: геометрия, способ, +0,000299999999999999974 :: двойной точности)) "" ряды удалены фильтром: 2" "-> Индекс сканирования с использованием places_index на world_osm_places (стоимость = 0,28 ... 8,30 строк = 1 ширина = 5587) (не выполняется)" "Индекс Cond: ( '0103000020E61000000100000005000000AA605452276353C043B0AA5E7E274540AA605452276353C00F7D772B4B34454044FAEDEBC05C53C00F7D772B4B34454044FAEDEBC05C53C043B0AA5E7E274540AA605452276353C043B0AA5E7E274540' :: геометрия && путь) "" -> Индекс сканирования с использованием countrys_index на world_osm_countrys (стоимость = 0,14 ... 8,16 строк = 1 ширина = 119944) (не выполняется)»" Индекс Cond: ( '0103000020E61000000100000005000000AA605452276353C043B0AA5E7E274540AA605452276353C00F7D772B4B34454044FAEDEBC05C53C00F7D772B4B34454044FAEDEBC05C53C043B0AA5E7E274540AA605452276353C043B0AA 5E7E274540 ':: geometry && geom) "" Общее время работы: 0,268 мс "


Смотреть видео: Данные OpenStreetMap: работа с линиями в PostgreSQL + PostGIS Константин Гордеев (September 2021).