Скажем, я хочу найти 20 ближайших к себе дел.
My table structure is like this:
BusinessID varchar(250) utf8_unicode_ci No None Browse distinct values Change Drop Primary Unique Index Fulltext
Prominent double No None Browse distinct values Change Drop Primary Unique Index Fulltext
LatLong point No None Browse distinct values Change Drop Primary Unique Index Fulltext
FullTextSearch varchar(600) utf8_bin No None Browse distinct values Change Drop Primary Unique Index Fulltext
With selected: Check All / Uncheck All With selected:
Print viewPrint view Propose table structurePropose table structureDocumentation
Add new fieldAdd field(s) At End of Table At Beginning of Table After
Indexes: Documentation
Action Keyname Type Unique Packed Field Cardinality Collation Null Comment
Edit Drop PRIMARY BTREE Yes No BusinessID 1611454 A
Edit Drop Prominent BTREE No No Prominent 0 A
Edit Drop LatLong BTREE No No LatLong (25) 0 A
Edit Drop sx_mytable_coords SPATIAL No No LatLong (32) 0 A
Edit Drop FullTextSearch FULLTEXT No No FullTextSearch 0
Есть 1,6 миллиона бизнесов. Конечно, глупо вычислять расстояние для всех и затем сортировать его.
Вот где гео пространственный индекс пинает правильно?
Так какого SQL-комманина мне нужно привести?
Замечания:
- Я использую MySQL пространственный индекс MySQL . Однако я не уточнил это раньше. Поэтому я приму тех, кто на него ответит, чтобы выразить свою признательность и задать еще один вопрос.
- Я не хочу вычислять расстояние для всей таблицы
- Я не хочу вычислять расстояние для любого региона, который все еще неэффективен
- Я хочу вычислить расстояние для разумного количества точек, потому что хочу отсортировать точки по расстоянию и иметь возможность отображать точки 1-20, 21-40, 41-60 и т. Д.
Ответы:
Пространственные запросы, безусловно, то, что нужно использовать.
С PostGIS я бы сначала попробовал что-то упрощенное, подобное этому, и настроил бы диапазон по мере необходимости:
Это позволит сравнить точки (на самом деле их ограничивающие рамки), используя пространственный индекс, поэтому это должно быть быстро. Другой подход, который приходит на ум, заключается в буферизации вашего местоположения и последующем пересечении этого буфера с исходными данными, что может быть даже более эффективным.
источник
Если все, что вам нужно, - это поиск точек приближения (запросы ближайших соседей), то вы не хотите использовать для этого старые ST_DWithin или ST_Distance + ORDER BY.
Уже нет.
Теперь, когда поставляется PostGIS 2.0, вы должны использовать поддержку индекса knngist (встроенная функция PostgreSQL). Это будет на порядки быстрее.
Выдержка из этой записи блога, которая описывает, как использовать knn gist без PostGIS :
Интересно, что при обходе индекса функции будут возвращаться в порядке близости, поэтому нет необходимости выполнять сортировку (то есть, упорядочивать) для результатов!
Однако, если вы хотите использовать его вместе с PostGIS, теперь это действительно легко. Просто следуйте этим инструкциям .
Соответствующая часть это:
Но не верьте мне на слово. Время это сам :)
источник
С PostGIS 2.0 на PostgreSQL 9.1 вы можете использовать индексированный оператор KNN ближайшего соседа , например:
Выше запрос должен в течение нескольких миллисекунд.
В течение следующих кратных 20, изменить до
OFFSET 20
,OFFSET 40
и т.д ...источник
<->
? Спасибо.<->
является оператором, который возвращает 2D-расстояние.MySQL Spatial
Все здесь говорят вам, как сделать это с PostgreSQL, используя KNN, не говоря вам о преимуществах. Используя MySQL, вы не можете определить ближайшего соседа, не рассчитав расстояние для всех соседей. Это очень медленно. С PostgreSQL это можно сделать для индекса. Ни MySQL, ни MariaDB в настоящее время не поддерживают KNN
источник