43 votes

Base de données: Meilleure performance pour interroger les données de localisation géographique?

J'ai une base de données MySQL. - Je stocker des maisons dans la base de données et effectuer littéralement juste 1 de la requête sur la base de données, mais j'ai besoin de cette requête pour être effectuée super rapide, et c'est de retourner toutes les maisons à l'intérieur d'une boîte carrée geo de latitude et de longitude.

SELECT * FROM homes 
WHERE geolat BETWEEN ??? AND ???
AND geolng BETWEEN ??? AND ???

Comment est la meilleure façon pour moi de stocker mes données géographiques afin que je puisse effectuer cette requête d'affichage de la maison à l'intérieur de la géolocalisation zone la plus rapide?

En gros:

  • Suis-je à l'aide de la meilleure instruction SQL à exécuter cette requête la plus rapide?
  • Toute autre méthode existe, peut-être même pas à l'aide d'une base de données, pour moi, à la requête de la façon la plus rapide à la suite de maisons à l'intérieur d'une boîte de géolocalisation limites?

Dans le cas où cela peut aider, j'ai ma table de base de données le schéma ci-dessous:

CREATE TABLE IF NOT EXISTS `homes` (
  `home_id` int(10) unsigned NOT NULL auto_increment,
  `address` varchar(128) collate utf8_unicode_ci NOT NULL,
  `city` varchar(64) collate utf8_unicode_ci NOT NULL,
  `state` varchar(2) collate utf8_unicode_ci NOT NULL,
  `zip` mediumint(8) unsigned NOT NULL,
  `price` mediumint(8) unsigned NOT NULL,
  `sqft` smallint(5) unsigned NOT NULL,
  `year_built` smallint(5) unsigned NOT NULL,
  `geolat` decimal(10,6) default NULL,
  `geolng` decimal(10,6) default NULL,
  PRIMARY KEY  (`home_id`),
  KEY `geolat` (`geolat`),
  KEY `geolng` (`geolng`),
) ENGINE=InnoDB  ;

Mise à JOUR

Je comprends spatiale prendra en compte la courbure de la terre, mais je suis plus intéressé par le retour de données geo le plus RAPIDE. À moins que ces spatiale de la base de données des paquets en quelque sorte le retour des données plus rapidement, s'il vous plaît ne pas recommander spatiale des extensions. Merci

Mise à JOUR 2

Veuillez noter, pas de un ci-dessous a vraiment répondu à la question. Je suis vraiment impatient de toute l'aide que je pourrais recevoir. Merci à l'avance.

14voto

Igor Zevaka Points 32586

Il existe un bon article sur les performances de géolocalisation de MySQL ici .

EDIT Plutôt sûr que cela utilise un rayon fixe. De plus, je ne suis pas certain à 100% que l'algorithme de calcul de la distance est le plus avancé (c.-à-d. Qu'il "forera" sur Terre).

Ce qui est important, c’est que l’algorithme n’est pas cher et vous donne une limite au nombre de rangs pour effectuer une recherche de distance appropriée.

5voto

Evert Points 17625

J'ai eu le même problème et j'ai écrit un article de blog en 3 parties. C'était plus rapide que l'index géographique.

Intro , Benchmark , SQL

2voto

tosh Points 2647

Si vous avez vraiment besoin d'aller pour les performances, vous pouvez définir des boîtes englobantes pour vos données et la carte de pré-calculer les boîtes englobantes à vos objets en matière d'insertion et de les utiliser plus tard pour les requêtes.

Si les jeux de résultats sont de taille raisonnable, vous pouvez toujours faire de l'exactitude des corrections dans la logique de l'application (plus facile à l'échelle horizontale qu'une base de données) tout en permettant de servir des résultats précis.

Jetez un oeil à Bret Slatkin est geobox.py qui contient de la documentation pour l'approche.

Je voudrais encore vous recommandons de vérifier PostgreSQL et PostGIS en comparaison à MySQL si vous avez l'intention de faire des requêtes plus complexes dans un avenir prévisible.

1voto

Ben Points 21

Voici une astuce que j'ai utilisé avec un certain succès est de créer de la tour des régions. C'est-à-dire, si vous avez un emplacement au 36.12345,-120.54321, et vous souhaitez les regrouper avec d'autres endroits qui sont à l'intérieur d'un demi-mile (approximative) de la boîte de grille, vous pouvez appeler sa région 36.12 x-120.54, et tous les autres endroits avec le même arrondi région va tomber dans la même boîte.

Évidemment, cela ne va pas vous obtenir un rayon propre, c'est à dire si le lieu que vous recherchez à est plus proche d'un bord que de l'autre. Toutefois, avec ce genre de set-up, il est assez facile de calculer les huit cases qui entourent votre lieu de résidence principale de la boîte. À savoir:

[36.13x-120.55][36.13x-120.54][36.13x-120.53]
[36.12x-120.55][36.12x-120.54][36.12x-120.53]
[36.11x-120.55][36.11x-120.54][36.11x-120.53]

Tirez sur tous les emplacements avec appariement d'arrondi étiquettes et ensuite, une fois que vous avez eux de la base de données, vous pouvez faire vos calculs de distance pour déterminer lequel utiliser.

1voto

Peter Lindqvist Points 6812

Les indices que vous utilisez sont bien des index B-tree et prennent en charge le mot clé BETWEEN dans votre requête. Cela signifie que l'optimiseur est capable d'utiliser vos index pour trouver les maisons dans votre "boîte". Cela ne signifie toutefois pas qu'il utilisera toujours les indices. Si vous spécifiez une plage contenant trop de "résultats", les index ne seront pas utilisés.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X