Як Yelp ефективно обчислює відстань у базі даних?


9

Наприклад, скажіть, у мене є таблиця:

Business(BusinessID, Lattitude, Longitude)

Усі, звичайно, індексуються. Також є 1 мільйон записів

Скажімо, я хочу знайти бізнес, найближчий до 106,5, наприклад, як мені це зробити?

Якщо я це роблю

SELECT *
FROM Business
WHERE (Some formula to compute distance here) < 2000

наприклад, або якщо я це роблю

SELECT *
FROM Business
TOP 20

Теоретично комп'ютеру доведеться обчислювати відстань для всіх бізнес, тоді як на практиці лише ті, які мають широту і довготу в межах певного діапазону, який слід обчислити.

То як я можу робити, наприклад, що в PHP або SQL?

Я вдячний відповіді поки що. Я використовую mysql, і вони не мають нічого більш ефективного, ніж очевидне рішення. У просторі MySQL також немає функції обчислення відстані.

Відповіді:


8

Якщо я правильно розумію питання (і я не впевнений, що це роблю), ви переживаєте за обчислення "(Some formula to compute distance here)"для кожного рядка в таблиці під час кожного запиту?

Це можна пом'якшити до певної міри за допомогою індексів на, latitudeі longitudeтому нам залишається лише обчислити відстань для "поля" точок, що містять коло, яке ми насправді хочемо:

select * from business
where (latitude>96 and latitude<116) and 
      (longitude>-5 and longitude<15) and 
      (Some formula to compute distance here) < 2000

Там, де 96, 116 тощо вибрано, щоб відповідати одиниці значення "2000" і точці на земній кулі, з якої ви обчислюєте відстані.

Наскільки точно для цього використовуються індекси, буде залежати від вашого RDBMS та вибору, який робить його планувальник.

Загалом, це примітивний спосіб оптимізації свого роду найближчого пошуку сусідів . Якщо ваша СУБД підтримує індекси GiST , як Postgres , то вам слід використовувати їх замість цього.


Я використовував mysql. Однак деякі двигуни mysql підтримують геопросторові, хоча і не innodb.
user4951

Я правий, що у вас немає можливості перейти з MySQL? У такому випадку, будь ласка, позначте питання mysql
Джек каже, спробуйте topanswers.xyz

Насправді я тепер додаю допоміжну таблицю myisam, як я це роблю тоді ефективно?
user4951

Ну я можу використовувати mongodb. Я цього не вирішив. Однак я найбільше знайомий з mysql.
user4951

1
Моя порада буде ознайомитись із postgres, якщо це взагалі можливо - порівняно з MongoDB він набагато більше схожий на MySQL і має суцільну історію з просторовими даними, а ваші коментарі в інших місцях вказують, що ви віддаєте перевагу "безкоштовно".
Джек каже, спробуйте topanswers.xyz

6

(Розкриття: я хлопець Microsoft SQL Server, тому на мої відповіді впливає це.)

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

Кешування важливо, якщо ви хочете масштабувати, періодично. Найшвидший запит - це той, який ти ніколи не робиш. Щоразу, коли користувач запитує найближчі речі до нього, ви зберігаєте його місцеположення та набір результатів у кеш-пам'яті на зразок Redis або запам’ятовується протягом кількох годин. Місцезнаходження компанії не змінюватиметься протягом 4 годин - ну, можливо, якщо хтось редагує компанію, але вам не обов’язково потрібно негайно оновлювати її у всіх наборах результатів.


Я не можу розібратися з вашого посилання, чи дійсно SQL Server індексує просторові дані таким чином, який корисний для отримання списку сусідніх точок - чи не так?
Джек каже, спробуйте topanswers.xyz


Справа в тому, що я використовую mysql, і я переконався, що в них немає алгоритму, більш ефективного, ніж те, що прописав Джек Дуглас. Цікаво, чи mysql зробить таку річ, як кешування. Microsoft SQL платний, а mysql безкоштовний
user4951

1
Місцезнаходження компанії не змінюватиметься постійно, однак місцеположення людей буде.
user4951

0

Yelp, ймовірно, використовує ГІС

PostgreSQL має довідкову реалізацію для ГІС з PostGIS . Yelp, можливо, використовує MySQL, який у всіх відношеннях поступається . У випадку чогось типу Yelp вони майже напевно зберігають координати,

  • Користувач
  • Потенційні місця призначення

Ці координати майже напевно є у WGS84 і зберігаються як тип географії. У PostgreSQL та PostGIS це виглядатиме приблизно так,

CREATE TABLE businesses (
  id   int               GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
  name text,
  geog geography(point)
);
CREATE INDEX ON businesses USING gist(geog);
.... fill table
ANALYZE businesses;

Вони б заповнили цю таблицю. Потім вони захоплюють координати WGS84 з вашого телефону та генерують запит, як-от це з алхімією SQL (у випадку Yelp),

SELECT *
FROM businesses AS b
WHERE ST_DWithin( b.geog, ST_MakePoint(userLong,userLat) );

Для отримання додаткової інформації дивіться наше та ознайомтесь з географічними інформаційними системами @ StackExchange

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.