Bagaimana Yelp menghitung jarak secara efisien dalam database?

9

Misalnya, katakan saya punya tabel:

Business(BusinessID, Lattitude, Longitude)

Semua diindeks tentu saja. Juga ada 1 juta catatan

Katakanlah saya ingin mencari bisnis yang paling dekat dengan 106,5, misalnya, bagaimana saya melakukannya?

Jika aku melakukan

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

misalnya, atau jika saya lakukan

SELECT *
FROM Business
TOP 20

Secara teori, komputer harus menghitung jarak untuk semua biz sementara dalam praktiknya hanya mereka yang memiliki lattitude dan bujur dalam rentang tertentu yang harus dihitung.

Jadi bagaimana saya bisa melakukan apa yang saya inginkan di PhP, atau SQL, misalnya?

Saya bersyukur dengan jawabannya sejauh ini. Saya menggunakan mysql dan mereka tidak memiliki sesuatu yang lebih efisien daripada solusi yang jelas. MySQL spasial juga tidak memiliki fungsi jarak komputasi.

pengguna4951
sumber

Jawaban:

8

Jika saya memahami pertanyaan dengan benar (dan saya tidak yakin saya mengerti), Anda khawatir tentang komputasi "(Some formula to compute distance here)"untuk setiap baris dalam tabel setiap kali Anda melakukan kueri?

Ini dapat dikurangi sampai derajat tertentu dengan menggunakan indeks latitudedan longitudekarenanya kita hanya perlu menghitung jarak untuk 'kotak' poin yang berisi lingkaran yang sebenarnya kita inginkan:

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

Di mana 96, 116 dll dipilih untuk mencocokkan unit nilai '2000' dan titik di dunia yang Anda hitung jaraknya.

Bagaimana tepatnya ini menggunakan indeks akan tergantung pada RDBMS Anda dan pilihan perencana yang dibuatnya.

Secara umum, ini adalah cara primitif untuk mengoptimalkan semacam pencarian tetangga terdekat . Jika RDBMS Anda mendukung indeks GiST , seperti postgres maka Anda harus mempertimbangkan untuk menggunakannya.

Jack mengatakan coba topanswers.xyz
sumber
Saya menggunakan mysql. Namun, beberapa mesin mysql mendukung geopatial meskipun tidak innodb.
user4951
Apakah saya benar bahwa Anda tidak memiliki opsi untuk berubah dari MySQL? Dalam hal ini harap beri tanda pada pertanyaan mysql
Jack mengatakan coba topanswers.xyz
Sebenarnya saya sekarang menambahkan tabel tambahan myisam sekarang bagaimana cara saya melakukannya dengan efisien?
user4951
Yah aku bisa menggunakan mongodb. Saya belum memutuskan itu. Namun, saya paling akrab dengan mysql.
user4951
1
Saran saya adalah membiasakan diri dengan postgres jika mungkin - dibandingkan dengan MongoDB jauh lebih mirip dengan MySQL dan memiliki sejarah yang kuat dengan data spasial, dan komentar Anda di tempat lain menunjukkan Anda lebih suka 'gratis'.
Jack bilang coba topanswers.xyz
6

(Pengungkapan: Saya seorang pria Microsoft SQL Server, jadi jawaban saya dipengaruhi oleh hal itu.)

Untuk benar-benar melakukannya secara efisien, ada dua hal yang Anda inginkan: caching dan dukungan data spasial asli. Dukungan data spasial memungkinkan Anda menyimpan data geografi dan geometri secara langsung dalam database tanpa melakukan perhitungan intensif / mahal dengan cepat, dan memungkinkan Anda membuat indeks untuk menemukan titik terdekat terdekat dengan lokasi Anda saat ini (atau rute yang paling efisien atau apa pun).

Caching itu penting jika Anda ingin skala, titik. Permintaan tercepat adalah yang Anda tidak pernah buat. Setiap kali seorang pengguna menanyakan hal-hal terdekat dengannya, Anda menyimpan lokasinya dan hasilnya disetel dalam cache seperti Redis atau memcached selama beberapa jam. Lokasi bisnis tidak akan berubah selama 4 jam - well, mereka mungkin jika seseorang mengedit bisnis, tetapi Anda tidak perlu itu harus segera diperbarui di semua set hasil.

Brent Ozar
sumber
Saya tidak dapat mengetahui dari tautan Anda apakah SQL Server benar-benar melakukan pengindeksan data spasial dengan cara yang berguna untuk mendapatkan daftar poin terdekat - bukan?
Jack bilang coba topanswers.xyz
Kelihatannya tidak
Jack berkata coba topanswers.xyz
Masalahnya adalah saya menggunakan mysql dan saya telah memverifikasi mereka tidak memiliki algoritma yang lebih efisien daripada apa yang diresepkan Jack Douglas. Saya bertanya-tanya apakah mysql akan melakukan hal seperti caching juga. Microsoft SQL dibayar dan mysql gratis
user4951
1
Lokasi bisnis tidak akan berubah setiap saat, namun lokasi orang akan berubah.
user4951
0

Yelp kemungkinan menggunakan SIG

PostgreSQL memiliki implementasi referensi untuk GIS dengan PostGIS . Yelp mungkin menggunakan MySQL yang lebih rendah dalam segala hal . Dalam hal sesuatu seperti Yelp, mereka hampir pasti menyimpan koordinat untuk,

  • Pengguna
  • Destinasi potensial

Koordinat tersebut hampir pasti dalam WGS84, dan disimpan sebagai tipe Geografi. Dalam PostgreSQL, dan PostGIS akan terlihat seperti ini,

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;

Mereka akan mengisi tabel itu. Kemudian mereka mengambil koordinat WGS84 dari ponsel Anda dan menghasilkan kueri, seperti ini dengan SQL Alchemy (dalam kasus Yelp),

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

Untuk informasi lebih lanjut lihat kami , dan lihat Sistem Informasi Geografis @ StackExchange

Evan Carroll
sumber