Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

ottimizzare la query del vicino più vicino su 70 milioni di nuvole di punti spaziali ad altissima densità su SQL Server 2008

Siamo spiacenti, ma questa non è una risposta SQL, ma un modo per ottenere prestazioni prevedibili assumendo determinati vincoli sui tuoi dati.

Con quale frequenza cambiano i dati? Se possibile, potresti pre-calcolare un grafico di ogni entità 5 vicini più vicini e usarlo per accelerare la tua selezione.?

Se questi dati sono per lo più di sola lettura, allora...

Come sono distribuiti uniformemente questi punti? Se conosci abbastanza uniformemente e bene la distribuzione, potresti eseguire la tua mappatura spaziale inserendo in un bucket ogni coordinata e indice in una tabella hash.

Se non è necessario avere i dati nel database, spostarli in un file mappato in memoria per ricerche hash rapide. (70 milioni di record dovrebbero entrare facilmente in memoria).

Ho utilizzato questa architettura per generare ricerche inferiori al millisecondo per la pubblicità display e la pertinenza dei motori di ricerca.

==Elaborazione==

Crei semplicemente una griglia di quadrati di dimensioni fisse (come una scacchiera) e mappi ogni punto nella griglia, e crei un elenco degli oggetti che appartengono a ciascuna delle caselle della griglia -- se regoli la dimensione di ciascuna correttamente, dovresti avere in media 5-50 punti in ogni quadrato -- Questo è in linea di principio un quad-tree ma senza l'albero per semplicità.

Per ogni bucket vuoto dopo aver sparso tutti i dati nei bucket, aggiungi le informazioni sui bucket più vicini che contengono dati.

Ora puoi numerare ogni bucket da sinistra a destra-line-ny-line in modo che ogni bucket abbia un numero univoco che può essere calcolato dalle coordinate -- e inserisci ogni bucket in una tabella hash, o se lo spazio lo consente proprio come una tabella di ricerca diretta.

Ora quando hai la tua query, calcoli semplicemente a quale bucket verrà eseguito il mapping e otterrai un elenco di oggetti in quel bucket, oppure otterrai un bucket "vuoto" che contiene i puntatori al bucket più vicino che ha contenuto .

Questo ti darà il primo elenco candidato di oggetti che stai cercando, e ora devi semplicemente correre e vedere quale è il più vicino.

Nel 99% dei casi sarebbe così, ma se sei preoccupato che ci siano (a) alcuni condidate nei bucket successivi che sono effettivamente più vicini, controlla semplicemente gli 8 bucket circostanti e vedi se puoi trova più vicino lì.

Se ora vuoi anche ottenere un elenco di tutti gli oggetti più vicini, calcola anche una semplice rete di 5 vicini più vicini per ogni oggetto, così ti ritroverai con una struttura dati come A->{B,C,D ,E,F}, SI->{LA,RE,G,H,I}, C->{LA,J,K,K,G,M}....

Ciò formerà una semplice rete che ora puoi attraversare con una variazione di Dijkstra qui per ottenere tutti i punti adiacenti al punto più vicino.

La costruzione delle strutture di dati richiederà tempo, ma una volta completata, la ricerca corretta e la restituzione di un set di dati possono essere eseguite in pochi millisecondi (esclusa qualsiasi comunicazione http o off-box della causa)

Spero che questo aiuti.