powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Поиск ближайших записей по координатам
2 сообщений из 2, страница 1 из 1
Поиск ближайших записей по координатам
    #38798440
Terol
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Доброго времени суток.

Пытаюсь оптимизировать следующю задачу.
Дано:
1. Кординаты объектов на карте
2. Координата пользователя, где он находится в данный момент

Нужно:
Показать ближайшие к пользователю объекты на карте, понятие ближайший задано расстоянием - 2000 м.

Весь функционал реализовал и все работает, но смущает что идет Seq Scan и не используется индекс (сейчас данных пока мало, но их кол-во будет расти).

Ниже лабораторный код (в нем ближайший задан как 300000):

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
create table qq (id serial, p geography(Point,4326), s int4);

insert into qq (p,s) select 
ST_SetSRID(ST_MakePoint(p.lat, p.long),4326 )
, (random()*1000)::int 
from (select (0.5 - random()) * 180 as lat, random()*90 as long from 
    (select generate_series(1,1000000)) as t) as p;


CREATE INDEX idx_spatial_pop_geom
  ON qq
  USING gist
  (p);



Сейчас использую запрос (300000 - граница ближайшего, ST_MakePoint(55.5, 45.45), 4326) - условные координаты пользователя)

Код: sql
1.
2.
select st_distance(p,ST_SetSRID(ST_MakePoint(55.5, 45.45), 4326)) AS RNG  from qq 
 where st_distance(p,ST_SetSRID(ST_MakePoint(55.5, 45.45), 4326)) < 300000



И по его плану видно, что индекс не используется

Код: plaintext
1.
Seq Scan on qq  (cost=0.00..357197.25 rows=333333 width=56)
  Filter: (_st_distance(p, '0101000020E61000000000000000C04B409A99999999B94640'::geography, 0::double precision, true) < 300000::double precision)

По следам встреч PostgreSQL узнал про <-> Однако запрос вида

Код: sql
1.
2.
select st_distance(p,ST_SetSRID(ST_MakePoint(55.5, 45.45), 4326)) AS RNG  from qq 
 ORDER BY p <-> ST_SetSRID(ST_MakePoint(55.5, 45.45), 4326)::geography  asc limit 10



выдает ошибку

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
ERROR:  operator does not exist: geography <-> geography
LINE 22:  ORDER BY p <-> ST_SetSRID(ST_MakePoint(55.5, 45.45), 4326):...
                     ^
HINT:  No operator matches the given name and argument type(s). You might need to add explicit type casts.
********** Error **********

ERROR: operator does not exist: geography <-> geography
SQL state: 42883
Hint: No operator matches the given name and argument type(s). You might need to add explicit type casts.
Character: 645

И я так понимаю что оператора <-> для geography нет

Выборка из 1М значений происходит ~1,6 c. Собственно как ускорить


С уважением,
Станислав Свириденко
...
Рейтинг: 0 / 0
Поиск ближайших записей по координатам
    #38798455
Terol
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Прошу прощения, сам спросил сам и отвечу.

Правильнее использовать функцию ST_DWithin ( http://postgis.org/documentation/manual-svn/ST_DWithin.html)

Пример для вышеописанной задачи

Код: sql
1.
2.
select st_distance(p,ST_SetSRID(ST_MakePoint(55.5, 45.45), 4326)) from qq 
where ST_DWithin(p, ST_SetSRID(ST_MakePoint(55.5, 45.45), 4326), 300000, true)
...
Рейтинг: 0 / 0
2 сообщений из 2, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Поиск ближайших записей по координатам
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]