Comment calculer la distance entre les coordonnées EFFICACEMENT dans Oracle
J'ai une grande base de données Oracle ( 720,000 enregistrements aprox) où chaque enregistrement possède ses propres coordonnées géographiques (lat & gnl) et j'ai besoin de sélectionner uniquement les enregistrements qui sont à une certaine distance d'un point à l'intérieur d'un rayon spécifique).
Actuellement, j'ai implémenté une fonction de distance (basé sur haversine) que j'ai trouvé dans un oracle forum, mais parce que la base de données est un peu grand, il passe environ 50 secondes pour sélectionner.
Toute recomendations sur la façon de faire thi efficacement?. Je sais qu'il y est une extension appelée oracle spatial & localisateur mais je ne sais pas si je peux l'acheter ou même comment cela fonctionne. Merci beaucoup à l'avance. En ce qui concerne meilleur
OriginalL'auteur Fgblanch | 2009-10-19
Vous devez vous connecter pour publier un commentaire.
Utiliser un meilleur algorithme. Au lieu de calculer réelle de la distance Euclidienne, ce qui nécessite une racine carrée de calcul, effectuez votre sélectionnez la distance linéaire, ce qui exige seulement la soustraction et l'addition. I. e. si votre point (10, 10) et de votre rayon est de 5, sélectionnez toutes les places avec les points à l'intérieur du carré formé par (10 +/- 5, 10 +/- 5).
Cela va prendre un petit nombre de faux positifs dans les coins de la place. Éliminer ces en double-vérifier les résultats dans votre application par le calcul de la bonne distance Euclidienne.
Une chose de plus. Pour le rendre plus efficace, nous avons créé deux index, l'un pour la latitude de la colonne et une de plus pour la longitude. Maintenant, la performance est très bonne.
OriginalL'auteur JSBձոգչ
Ne fournissent plus de détails sur le format spécifique de la Lat et Long de valeurs, ainsi que la formule utilisée pour la mise en œuvre de haversine.
Il existe trois approches qui peuvent accélérer les choses. Selon la situation, nous pouvons faire au moins deux de ces.
De mauvaises herbes comme le nombre d'enregistrements que possible par une simple valeur de l'attribut comparaison.
Pour ces dossiers, nous n'avons pas besoin de calculer quoi que ce soit.
Par exemple, convertir le rayon maximal exigence d'un [généreuse mais approximatif] plage de la Longitude (et, éventuellement, latitude) des valeurs qui seraient admissibles
Utiliser un autre (éventuellement approximatives) de mesure de distance.
Par exemple, il peut être plus rapide pour calculer le carré de la eucldidian distance, basé sur un arrondi coordonnées. (Et bien sûr de faire la comparaison avec le carré du rayon souhaité)
D'améliorer la façon dont les haversine formule est mis en œuvre.
lat et long sont flottent des valeurs dans des colonnes distinctes. La mise en application que j'ai utilisé, j'ai trouvé dans ce forum: forums.oracle.com/forums/thread.jspa?threadID=477747 la ushitaki.
OriginalL'auteur mjv
Un couple de suggestions, si vous n'êtes pas déjà en train de le...
Depuis le Haversine calcul nécessite la mesure des angles en radians, si vous stockez de la latitude et de la longitude en degrés, ajouter un couple de colonnes et de précalculer le radian équivalents. Plus généralement, pré-calculer l'une des valeurs de la fonction que vous pouvez pour la formule et de les stocker.
Envisager d'utiliser une simple fonction pour éliminer les points qui sont bien à l'extérieur du rayon, de l'exécution de l'Haversine fonctionner uniquement sur ceux qui sont de potentiels matchs basée sur la simple fonction. Pour les diplômes que vous pourriez utiliser SQRT( (69.1*dLat)2 + (53*dLong)2) ) et d'utiliser certaines fudge factor (10%). Exécutez votre Haversine calcul uniquement sur les points qui correspondent à la plus grossière approximation si vous avez besoin de plus que ce que le simple calcul fournit.
+1, en particulier pour le point 2.
Je pense que j'ai été en supposant que la distance réelle qui serait nécessaire dans le cadre de la sortie, mais si non, alors vous pouvez simplement le carré de la distance pour la comparaison.
OriginalL'auteur tvanfosson
Si vous avez la licence puis de l'Oracle Spatial pourrait être d'utiliser
Oracle Docs - Oracle Spatial
Je ne l'ai pas utilisé, mais une analyse rapide de la documentation serait point à la fonction SDO_WITHIN_DISTANCE
OriginalL'auteur Paul James
Est le "à distance" d'une certaine façon constante? IE êtes-vous toujours à la recherche de "tous les points à moins de 1 mile", ou ne le rayon de changement?
Quel est le pourcentage du nombre total d'enregistrements attendez-vous pour revenir en toute requête? 10%? .10%?
Si vous aurez toujours le même rayon, de construire une grille de carrés de la même longueur que le rayon. Attribuer à chacun une liste de cases voisines. Chaque point de savoir quelle place il est, à partir de laquelle vous pouvez obtenir une liste de toutes les cases voisines. Ensuite, exécutez le calcul uniquement sur les points de ces carrés. Ceci est similaire pour les autres réponses qui ont surgi, mais sera plus rapide, car les calculs linéaires sont approchées dans un indexée de recherche plutôt que calculée entre chaque point.
Même avec un rayon variable, vous pouvez toujours utiliser le ci-dessus, mais vous aurez à calculer la façon dont beaucoup de "voisins" pour y inclure. Ce sont seulement possible si vous êtes l'espoir d'obtenir un petit sous-ensemble du total de toute requête individuelle.
OriginalL'auteur David Oneill
Si vous n'avez pas besoin de la distance à être trop précis, vous pouvez traiter la terre comme plat. De cette discussion:
J'ai récemment fait quelques optimisation de mysql (expliqué ici: http://www.mooreds.com/wordpress/archives/000547 [désolé, je ne reçois 1 lien hypertexte par post] ), mais je suis pas sûr de savoir comment la plupart des étapes, je suis allé à travers sont applicables à Oracle. Certains le sont sans aucun doute (comme l'utilisation d'une boîte englobante si possible).
OriginalL'auteur mooreds
Vous pouvez obtenir un beaucoup plus précis... si vous modifiez le 53.0 nombre magique... de prendre également en compte la variation de la latitude. (Obtenir progressivement plus petites, comme vous déplacer vers les pôles.)
Que la magie de formule magique?
Ou, plus près de la forme que vous utilisiez: x = 69.1 * (lat2 - lat1); y = 69.1 * (lon2 - lon1) * cos(lat1/57.3); à Partir de meridianworlddata.com/Distance-Calculation.asp
OriginalL'auteur Sally
Tout d'abord, Haversine n'est pas parfait, parce que la Terre n'est pas une sphère parfaite - lire http://www.movable-type.co.uk/scripts/latlong-vincenty.html
Deuxième PL/SQL n'est pas un outil parfait pour le programme de calculs avec le nombre de lignes de code qui sera appelé à de nombreuses reprises. Si vous allez avec Java ou C++ mise en œuvre de votre math, vous donnera énorme amélioration de la performance. Code Java ou C++ peut être appelé à partir d'Oracle, comme une fonction.
Tiers des personnes qui ont commenté que vous avez besoin de couper autant de points que possible avec de simples rectangulaire de boxe sont très correctes. Créer un index en fonction de la longitude et de la latitude des colonnes, il aidera à exécuter que la boxe clause.
Enfin, je ne pense pas que Oracle Spatial doit être en jeu ici, c'est inutile. Si vous l'avez déjà et créé colonne SDO_GEOMETRY, c'est une histoire, mais si ce n'est pas que je ne voudrais pas le considérer.
OriginalL'auteur DimaA6_ABC