Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

optimiser la requête du plus proche voisin sur 70 millions de nuages ​​de points spatiaux à très haute densité sur SQL Server 2008

Désolé, mais ce n'est pas une réponse SQL, mais un moyen d'obtenir des performances prévisibles en supposant certaines contraintes sur vos données.

À quelle fréquence les données changent-elles ? Si possible, pourriez-vous pré-calculer un graphique de chaque entité 5 voisins les plus proches, et l'utiliser pour accélérer votre sélection ?

Si ces données sont principalement en lecture seule, alors...

Dans quelle mesure ces points sont-ils répartis uniformément ? Si la distribution est assez uniforme et bien connue, alors pourriez-vous lancer votre propre mappage spatial en regroupant chaque coordonnée et index dans une table de hachage.

Si vous n'avez pas besoin d'avoir les données dans la base de données, déplacez-les vers un fichier mappé en mémoire pour des recherches de hachage rapides. (70 millions d'enregistrements devraient facilement tenir en mémoire).

J'ai utilisé cette architecture pour générer des recherches inférieures à la milliseconde pour la publicité display et la pertinence des moteurs de recherche.

==Élaboration==

Vous créez simplement une grille de carrés de taille fixe (comme un échiquier), et vous mappez chaque point dans la grille, et vous créez une liste des objets qui appartiennent à chacune des cases de la grille -- si vous ajustez la taille de chaque case correctement, vous devriez avoir en moyenne 5 à 50 points dans chaque carré -- Il s'agit en principe d'un quad-tree mais sans l'arbre pour plus de simplicité.

Pour chaque compartiment vide après avoir dispersé toutes les données dans des compartiments, vous ajoutez des informations sur les compartiments les plus proches contenant des données.

Vous pouvez maintenant numéroter chaque seau de gauche à droite-ligne-ny-ligne afin que chaque seau ait un numéro unique qui peut être calculé à partir des coordonnées - et vous insérez chaque seau dans une table de hachage, ou si l'espace le permet aussi une table de recherche directe.

Maintenant, lorsque vous avez votre requête, vous calculez simplement à quel seau sera mappé, et vous obtiendrez soit une liste d'objets dans ce seau, soit vous obtiendrez un seau "vide" qui contient les pointeurs vers le seau le plus proche qui a du contenu .

Cela vous donnera votre première liste de candidats d'objets que vous recherchez, et maintenant vous n'avez plus qu'à courir et voir lequel est le plus proche.

Dans 99 % des cas, ce serait le cas - mais si cela vous inquiète, il y a (a) soit des conditions dans les seaux suivants qui sont en fait plus proches, alors vérifiez simplement les 8 seaux environnants et voyez si vous pouvez trouver plus près là-bas.

Si vous souhaitez maintenant également obtenir une liste de tous les objets les plus proches, calculez également un réseau simple de 5 voisins les plus proches pour chaque objet, de sorte que vous vous retrouverez avec une structure de données comme A-> {B, C, D ,E,F}, B->{A,D,G,H,I}, C->{A,J,K,G,M}....

Cela formera un réseau simple que vous pouvez maintenant traverser avec une variante de Dijkstra ici pour obtenir tous les points adjacents à votre point le plus proche.

Construire les structures de données prendra du temps, mais une fois terminé, la recherche et le retour d'un ensemble de données peuvent être effectués en moins de millisecondes (sans compter les communications http ou hors boîte)

J'espère que cela vous aidera.