Yelp, veritabanındaki mesafeyi nasıl verimli bir şekilde hesaplar?


9

Örneğin, benim bir tablo var diyelim:

Business(BusinessID, Lattitude, Longitude)

Elbette hepsi endekslenir. Ayrıca 1 milyon kayıt var

Diyelim ki 106,5'e en yakın işletmeleri bulmak istiyorum, örneğin bunu nasıl yaparım?

Eğer yaparsam

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

örneğin, eğer yaparsam

SELECT *
FROM Business
TOP 20

Teorik olarak, bilgisayar pratikte sadece hesaplanması gereken belirli bir aralıktaki enlem ve boylamı olanlar için tüm mesafeyi hesaplamak zorunda kalacaktır.

Peki PhP veya SQL'de istediğimi nasıl yapabilirim?

Şimdiye kadar verilen cevaptan dolayı minnettarım. MySQL kullanıyorum ve belirgin çözüm daha verimli bir şey yok. MySQL uzamsal hesaplama mesafesi fonksiyonuna da sahip değildir.

Yanıtlar:


8

Soruyu doğru anlarsam (ve emin değilim), "(Some formula to compute distance here)"her sorgu yaptığınızda tablodaki her satır için bilgi işlemden endişe duyuyorsunuz?

Bu, dizinleri kullanarak bir dereceye kadar hafifletilebilir latitudeve longitudebu nedenle sadece istediğimiz daireyi içeren noktaların 'kutu' mesafesini hesaplamamız gerekir:

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

Burada 96, 116 vb. '2000' değerinin birimine ve mesafeleri hesapladığınız dünyadaki noktaya uyacak şekilde seçilir.

Bunun dizinleri tam olarak nasıl kullanacağı RDBMS'nize ve planlamacısının yaptığı seçimlere bağlıdır.

Genel olarak, bu bir tür en yakın komşu aramayı optimize etmenin ilkel bir yoludur . RDBMS'niz postgres gibi GiST dizinlerini destekliyorsa , bunun yerine bunları kullanmayı düşünmelisiniz.


MySQL kullandım. Bununla birlikte, bazı mysql motorları innodb olmasa da jeopatialı destekler.
user4951

MySQL'den değiştirme seçeneğiniz olmadığı doğru mu? Bu durumda lütfen soru mysql olarak
Jack diyor denemek topanswers.xyz

Aslında şimdi myisam yardımcı tablo eklemek şimdi nasıl verimli o zaman?
user4951

Mongodb kullanabilirim. Buna ben karar vermedim. Ancak, en çok mysql aşinayım.
user4951

1
Benim tavsiyem, mümkünse postgres'lere aşina olmak olacaktır - MongoDB'ye kıyasla MySQL'e çok daha benzerdir ve uzamsal verilerle sağlam bir geçmişe sahiptir ve başka bir yerde yorumlarınız 'ücretsiz' tercih ettiğinizi gösterir.
Jack diyor ki topanswers.xyz

6

(Açıklama: Ben bir Microsoft SQL Server kullanıcısıyım, bu yüzden cevaplarım bundan etkileniyor.)

Gerçekten verimli bir şekilde yapmak için istediğiniz iki şey vardır: önbellekleme ve yerel uzamsal veri desteği. Uzamsal veri desteği, coğrafi / geometri verilerini anında yoğun / pahalı hesaplamalar yapmadan doğrudan veritabanında depolamanızı sağlar ve geçerli konumunuza (veya en etkili yolunuza ya da her neyse) en hızlı noktayı bulmak için dizinler oluşturmanıza olanak tanır.

Ölçeklemek istiyorsanız, önbellekleme önemlidir. En hızlı sorgu hiç yapmadığınız sorudur. Bir kullanıcı kendisine en yakın şeyleri istediğinde, yerini ve sonucunu Redis gibi bir önbellekte saklar veya bir saat boyunca memcached. İşletme konumları 4 saat boyunca değişmeyecek - birisi bir işletmeyi düzenlerse bu durum değişebilir, ancak bunun tüm sonuç kümelerinde hemen güncellenmesi gerekmez.


SQL Server uzamsal verileri gerçekten yakındaki noktaların bir listesini almak için yararlı bir şekilde dizin olup olmadığını bağlantıdan çalışamam - değil mi?
Jack diyor ki topanswers.xyz


Mesele şu ki, mysql kullanıyorum ve Jack Douglas'ın öngördüğünden daha verimli bir algoritmaya sahip olmadıklarını doğruladım. Mysql'in önbellekleme gibi bir şey yapıp yapmayacağını merak ediyorum. Microsoft SQL ücretli ve mysql ücretsiz
user4951

1
İşletme konumu her zaman değişmeyecek, ancak insanların konumu değişmeyecek.
user4951

0

Yelp muhtemelen CBS kullanıyor

PostgreSQL, PostGIS'li CBS için referans uygulamasına sahiptir . Yelp her açıdan daha düşük olan MySQL kullanıyor olabilir . Yelp gibi bir şey söz konusu olduğunda, neredeyse kesinlikle koordinatlarını tutarlar,

  • Kullanıcı
  • Potansiyel destinasyonlar

Bu koordinatlar neredeyse kesinlikle WGS84'tedir ve Coğrafya türü olarak saklanır. PostgreSQL ve PostGIS'de böyle bir şey olurdu,

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;

Bu masayı dolduracaklardı. Sonra WGS84 koordinatlarını telefonunuzdan alırlar ve SQL Alchemy ile (Yelp durumunda),

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

Daha fazla bilgi için ve Coğrafi Bilgi Sistemleri @ StackExchange'e göz atın

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.