Comment Yelp calcule-t-il efficacement la distance dans la base de données?


9

Par exemple, disons que j'ai une table:

Business(BusinessID, Lattitude, Longitude)

Tous sont bien sûr indexés. Il y a aussi 1 million d'enregistrements

Supposons que je veuille trouver des entreprises les plus proches de 106,5, par exemple, comment dois-je procéder?

Si je fais

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

par exemple, ou si je le fais

SELECT *
FROM Business
TOP 20

En théorie, l'ordinateur devra calculer la distance pour tous les biz alors qu'en pratique, seuls ceux dont la lattitude et la longitude se situent dans une certaine plage devraient être calculés.

Alors, comment puis-je faire ce que je veux en PhP ou en SQL, par exemple?

Je suis reconnaissant de la réponse jusqu'à présent. J'utilise mysql et ils n'ont rien de plus efficace que la solution évidente. MySQL spatial n'a pas non plus de fonction de calcul de distance.

Réponses:


8

Si je comprends bien la question (et je ne suis pas sûr de le faire), vous vous inquiétez de calculer "(Some formula to compute distance here)"pour chaque ligne du tableau chaque fois que vous effectuez une requête?

Cela peut être atténué dans une certaine mesure en utilisant les index latitudeet longitudenous n'avons donc qu'à calculer la distance pour une `` boîte '' de points contenant le cercle que nous voulons réellement:

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

Où 96, 116, etc. sont choisis pour correspondre à l'unité de la valeur '2000' et au point du globe à partir duquel vous calculez les distances.

La précision de l'utilisation des index dépendra de votre SGBDR et des choix que fera son planificateur.

En termes généraux, il s'agit d'une manière primitive d'optimiser une sorte de recherche de voisin le plus proche . Si votre SGBDR prend en charge les index GiST , comme les postgres, vous devriez envisager de les utiliser à la place.


J'ai utilisé mysql. Cependant, certains moteurs mysql supportent géopatial mais pas innodb.
user4951

Ai-je raison de dire que vous n'avez pas la possibilité de changer de MySQL? Dans ce cas, veuillez taguer la question mysql
Jack dit essayer topanswers.xyz

En fait, j'ajoute maintenant une table auxiliaire de myisam maintenant comment puis-je le faire efficacement alors?
user4951

Eh bien, je peux utiliser mongodb. Je n'ai pas décidé cela. Cependant, je connais bien mysql.
user4951

1
Mon conseil serait de se familiariser avec les postgres si c'est possible - par rapport à MongoDB, il est beaucoup plus similaire à MySQL et a une histoire solide avec des données spatiales, et vos commentaires ailleurs indiquent que vous préférez `` gratuit ''.
Jack dit d'essayer topanswers.xyz le

6

(Divulgation: je suis un gars de Microsoft SQL Server, donc mes réponses sont influencées par cela.)

Pour vraiment le faire efficacement, il y a deux choses que vous voulez: la mise en cache et la prise en charge des données spatiales natives. La prise en charge des données spatiales vous permet de stocker des données de géographie et de géométrie directement dans la base de données sans effectuer de calculs intensifs / coûteux à la volée, et vous permet de créer des index pour trouver très rapidement le point le plus proche de votre emplacement actuel (ou l'itinéraire le plus efficace ou autre).

La mise en cache est importante si vous souhaitez évoluer, point final. La requête la plus rapide est celle que vous ne faites jamais. Chaque fois qu'un utilisateur demande les choses les plus proches de lui, vous stockez son emplacement et le jeu de résultats dans un cache comme Redis ou memcached pendant une période de plusieurs heures. Les emplacements des entreprises ne changeront pas pendant 4 heures - eh bien, ils pourraient le faire si quelqu'un modifie une entreprise, mais vous n'avez pas nécessairement besoin que cela soit mis à jour immédiatement dans tous les ensembles de résultats.


Je ne peux pas déterminer à partir de votre lien si SQL Server indexe vraiment les données spatiales d'une manière utile pour obtenir une liste de points à proximité - n'est-ce pas?
Jack dit d'essayer topanswers.xyz


Le fait est que j'utilise mysql et j'ai vérifié qu'ils n'ont pas d'algorithme plus efficace que ce que Jack Douglas a prescrit. Je me demande si mysql fera ce genre de chose comme la mise en cache non plus. Microsoft SQL est payant et mysql est gratuit
user4951

1
L'emplacement de l'entreprise ne changera pas tout le temps, mais l'emplacement des personnes le sera.
user4951

0

Yelp utilise probablement le SIG

PostgreSQL a l'implémentation de référence pour les SIG avec PostGIS . Yelp utilise peut-être MySQL, qui est inférieur à tous égards . Dans le cas de quelque chose comme Yelp, ils gardent presque certainement les coordonnées,

  • L'utilisateur
  • Les destinations potentielles

Ces coordonnées sont presque certainement dans WGS84, et stockées comme type Geography. Dans PostgreSQL et PostGIS, cela ressemblerait à quelque chose comme ça,

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;

Ils rempliraient ce tableau. Ensuite, ils saisissent les coordonnées WGS84 de votre téléphone et génèrent une requête, comme celle-ci avec SQL Alchemy (dans le cas de Yelp),

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

Pour plus d'informations, consultez notre et consultez les systèmes d'information géographique @ StackExchange

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.