Виконуєте запит на обмежувальний ящик у PostGIS? [зачинено]


22

У мене є таблиця PostgreSQL, майже 2 мільйони рядків, з довгим полім coordinatesформи POINT(-73.4938 33.2405).

Припустимо, що на цьому полі є геопросторовий індекс, який найефективніший і найшвидший спосіб вибрати всі рядки в довільному обмежувальному полі?

Коробка , як SW long-lat: -74.0042 40.7688, NE long-lat: -73.8809 40.7984.


Ваші збережені координати вже є довгими або вони сіткою (X, Y)?
Мартін

1
Тут виконують просту математику ... Якщо point.x більший за SW.x і менший ніж NE.x, а point.y більший за SW.y і одночасно менший ніж NE.y, точка лежить всередині MBR. Я не знаю, чи швидше це, ніж використання просторового запиту. Ви проти спробувати?
Міхал Циммерманн

@zimmi: Він насправді не заявляє, що предмети - це лише пункти; вони могли бути складними геометріями.
Мартін Ф

Вони є тільки точки, хоча ;-). Вони тривалий у формі POINT (-73.4938 33.24059), що зберігається як WKB.
Avishai

Я відредагував Q (і моє A), щоб відобразити цю інформацію. :-)
Мартін Ф

Відповіді:


24

Припускаючи, що задані межі поля обмеження знаходяться в тій самій просторовій системі відліку, що і збережені координати, і ви знаєте, який просторовий оператор (перетинається або міститься) вам потрібен:

SELECT *
FROM   my_table
WHERE  coordinates 
    && -- intersects,  gets more rows  -- CHOOSE ONLY THE
    @ -- contained by, gets fewer rows -- ONE YOU NEED!
    ST_MakeEnvelope (
        xmin, ymin, -- bounding 
        xmax, ymax, -- box limits
        my_srid)

Крім того, якщо ви віддаєте перевагу звучання "містить" (замість "міститься в"), WHEREпункт слід перевернути:

WHERE  ST_MakeEnvelope (...)
    ~ -- contains, gets same fewer rows 
    coordinates 

PS: Враховуючи (ОП після публікації вище), що записи - це прості точки, я вважаю, що різниця між "перетинається" та "стримуванням" стає дуже тонкою, впливаючи лише на точки на краях обмежувального поля.


це хороший момент. Містить добре, оскільки ви не зможете побачити маркер карти, якщо він знаходиться на межі (тобто, можливо, хром браузера).
Avishai

What's the fastest ...?: OP
Magno C

Будьте в курсі: &&і @, здається, не працюють, коли перетинаються з геометрією багатокутника. У цьому випадку використовуйте ST_Intersects(latlng_column,ST_GeomFromText('Polygon ((...))',4326))або альтернативноST_Contains
Олексій

4
SELECT ST_Y(the_geom) AS latitude, ST_X(the_geom) as longitude
from units u where the_geom && ST_MakeEnvelope(left, bottom, right, top, 4326)

1
Не обов’язково говорити, що 4326 є SRID.
Magno C

2

Мабуть, мені не вистачає балів, щоб додати коментар, тому я використовую цей відповідь, просто кажу, що я спробував обидва ST_MakeEnvelope і математики порівняти "x> min_x і x <max_x і y> min_y і y <max_y". .. в середньому ST_MakeEnvelope займає 60 мс, а порівняння математики займає 155 мс на моєму конкретному запиті bbox.

Отже, просторовий пошук ST_MakeEnvelope повинен бути швидшим порівняно з математикою!


1
Насправді, якщо створити правильні індекси min_x, max_x, min_y та max_y, буде набагато швидше. У мене дуже великий набір даних (понад 3 мільйони полігонів), і я робив і INDEXнад ST_MakeEnvelope і (ST_XMax, ST_XMin, ST_YMax, ST_YMin), і різниця дуже корисна для математики. Математика зайняла мене менше 20-ти (INDEX + Query), тоді як перехрестя конвертів зайняло 2 хвилини (я здався, коли досяг 2min, 40s лише для просторової індексації)
caiohamamura
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.