Геопространственный запрос PostGis медленнее, чем настраиваемый скрипт на Python - PullRequest
0 голосов
/ 30 января 2019

Я довольно новичок в PostGis, и я использую его для выполнения геопространственных запросов, но, похоже, довольно медленно возвращает желаемые результаты.

До того, как я использовал скрипт на python, который обычно возвращает результатыв течение более или менее 5 секунд (поиск более 1,2 млн элементов).

Чтобы быстрее получить этот результат, я перенес проблему на postgis, но, как я уже писал ранее, это требует большезатем 20 секунд для того же задания.

Точнее, каждый элемент состоит из точки (широта) и строки (метка для точки)

Я использую докерский постгис (https://hub.docker.com/r/mdillon/postgis) на моем I7 16 ГБ ОЗУ (Ubuntu 18.04)

Я создал БД следующим образом:

CREATE DATABASE demo;
\c demo
create extension postgis;
CREATE TABLE mypoints ( id serial primary key, name varchar(50), the_geom geometry(POINT,4326) );

и вставил точки (1,2M),с помощью сценария Python, таким образом

INSERT INTO cities (the_geom, name) VALUES (ST_GeomFromText('POINT(-3.782 40.4351)',4326), 'point_label');

Я использовал следующий запрос:

select name from cities where ST_Distance_Sphere(the_geom,ST_GeomFromText('POINT(-3.713 40.4321)',4326))<500;

Я делаю что-то не так? Как это возможно, что мой код Python быстреечем оптимизированный запрос по геопространственной проблеме?

1 Ответ

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

Вы не в полной мере используете PostGis, потому что еще не используете пространственные индексы.

Чтобы создать индекс в своей таблице:

create index my_index_points_gist on mypoints using gist(the_geom);

Затем выполните cluster иanalyze на вашем столе:

cluster mypoints using my_index_points_gist;
analyze mypoints;

Я вижу, что вы используете сферическое расстояние, было бы лучше, если бы вы использовали тип географии:

CREATE TABLE mypoints ( id serial primary key, name varchar(50), geog geography );

Вставьте данные обычным способом, добавляя приведение к типу geograhy:

INSERT INTO cities (geog, name) VALUES (ST_GeomFromText('POINT(-3.782 40.4351)',4326)::geography, 'point_label');

Либо просто добавьте дополнительный столбец geography:

alter table mypoints add column geog::geography;
update table mypoints set geog = the_geom::geography;

создать индекс, но на этот раз с использованием geog

create index my_index_points_gist_geog on mypoints using gist(geog);
cluster mypoints using my_index_points_gist_geog;
analyze mypoints;

А для запроса вы можете использовать:

select name from cities
where ST_Distance(geog,ST_GeomFromText('POINT(-3.713 40.4321)',4326)::geog)<500;

Или еще лучше:

select name from cities
where ST_DWITHIN(geog,ST_GeomFromText('POINT(-3.713 40.4321)',4326)::geog,500);

Для справки: Тип географии postgis

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...