Как запросить данные postgis по ближайшей точке и вернуть результаты только для этой точки? - PullRequest
0 голосов
/ 30 января 2019

У меня есть таблица баллов postgis, 460 миллионов записей.Он имеет отметку времени и столбец точек.

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

SELECT thevalue 
FROM thetable 
WHERE ST_DWithin (thepoint, ST_MakePoint($get_lon, $get_lat), 0.04) 
ORDER BY thedate 
LIMIT 1000

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

1 Ответ

0 голосов
/ 30 января 2019

Какой у тебя король геометрии?какую проекцию вы используете?Я предполагаю, что ваши точки указаны в wgs84 (epsg: 4326)

Если вы хотите, чтобы расстояния были точными, лучше использовать географию в расчетах:

alter points_table add column geog geography
update points_table set geog = geom::geography

создайтеИндекс и запустить cluster и analyze, чтобы ускорить запросы

create index my_index_geog on points_table using gist(geog) /* change geog for geom if using geometry */
cluster points_table using my_index_geog
analyze points_table

, чтобы получить ближайшую точку:

SELECT point_id 
FROM points_table
ORDER BY geog <-> ST_SetSrid(ST_MakePoint($get_lon, $get_lat),4326)::geography limit 1;

все вместе, чтобы получить значения:

select value
from table
where point_id = (SELECT point_id 
FROM points_table
ORDER BY geog <-> ST_SetSrid(ST_MakePoint($get_lon, $get_lat),4326)::geography limit 1)
order by thedate
limit 1000;

дополнительно я бы предложил сохранить таблицу, содержащую только идентификаторы точек и геометрию / географию, чтобы запрос на ближайшую точку выполнялся быстрее.Если вы создадите такую ​​таблицу с именем only_points, запрос будет выглядеть следующим образом:

select value
from table
where point_id = (SELECT point_id 
FROM only_points
ORDER BY geog <-> ST_SetSrid(ST_MakePoint($get_lon, $get_lat),4326)::geography limit 1)
order by thedate
limit 1000;

Если вам нужно продолжать использовать geometry, то вам нужно будет создать индекс по геометрии, кластер на основеgeom и выполните запрос:

select value
from table
where point_id = (SELECT point_id 
FROM points_table
ORDER BY geom::geography <-> ST_SetSrid(ST_MakePoint($get_lon, $get_lat),4326)::geography limit 1)
order by thedate
limit 1000;

Однако это будет медленнее, потому что вы будете переходить в географию на каждом шаге

см. KNN в Postgis и География и индексы PostGIS

...