sql >> Database >  >> RDS >> Sqlserver

optimaliseer zoekopdracht voor naaste buren op 70 miljoen ruimtelijke puntenwolken met extreem hoge dichtheid op SQL Server 2008

Sorry, maar dit is geen SQL-antwoord, maar een manier om voorspelbare prestaties te krijgen, uitgaande van bepaalde beperkingen op uw gegevens.

Hoe vaak veranderen de gegevens? Kunt u, indien mogelijk, vooraf een grafiek berekenen van elke entiteit 5 naaste buren, en die gebruiken om uw selectie te versnellen?

Als deze gegevens meestal alleen-lezen zijn, dan...

Hoe gelijkmatig zijn deze punten verdeeld? Als de verdeling redelijk gelijkmatig en goed bekend is, zou je dan je eigen ruimtelijke mapping kunnen maken door elke coördinaat en index in een hashtabel te plaatsen.

Als u de gegevens niet in de database hoeft te hebben, verplaats ze dan naar een geheugen toegewezen bestand voor snelle hash-zoekopdrachten. (records van 70 meter moeten gemakkelijk in het geheugen passen).

Ik heb deze architectuur gebruikt om zoekopdrachten van minder dan een milliseconde te genereren voor display-advertenties en relevantie voor zoekmachines.

==Uitwerking==

U maakt eenvoudig een raster van vierkanten met een vaste grootte (zoals een schaakbord), en u brengt elk punt in kaart in het raster, en u maakt een lijst van de objecten die in elk van de rastervakken horen -- als u de grootte van elk aanpast correct is, zou je gemiddeld 5-50 punten in elk vierkant moeten hebben -- Dit is in principe een quad-tree maar zonder de tree voor de eenvoud.

Voor elke bucket die leeg is nadat u alle gegevens in buckets heeft verspreid, voegt u informatie toe over de dichtstbijzijnde buckets die gegevens bevatten.

U kunt nu elke bucket van links naar rechts-regel-ny-regel nummeren, zodat elke bucket een uniek nummer heeft dat kan worden berekend op basis van de coördinaten -- en u voegt elke bucket in een hashtabel in, of als de ruimte het toelaat net zo een rechte opzoektabel.

Als u nu uw vraag heeft, berekent u eenvoudig naar welke bucket dat gaat, en u krijgt ofwel een lijst met objecten in die bucket, of u krijgt een 'lege' bucket die de verwijzingen bevat naar de dichtstbijzijnde bucket met inhoud .

Dat geeft je de eerste kandidatenlijst van objecten die je zoekt, en nu hoef je alleen maar door te rennen en te kijken welke het dichtst in de buurt is.

In 99% van de gevallen zou dat het zijn - maar als u zich daar zorgen over maakt (a) zijn er ofwel enkele condidates in de next-over-emmers die eigenlijk dichterbij zijn, controleer dan gewoon de 8 omliggende emmers en kijk of u kunt vind je daar dichterbij.

Als je nu ook een lijst wilt krijgen van alle objecten die het dichtst bij zijn, bereken dan ook een eenvoudig netwerk van 5 dichtstbijzijnde buren voor elk object, zodat je een datastructuur krijgt zoals A->{B,C,D ,E,F}, B->{A,D,G,H,I}, C->{A,J,K,G,M}....

Dat zal een eenvoudig netwerk vormen dat je nu kunt doorkruisen met een variatie van Dijkstra hier om alle punten naast uw dichtstbijzijnde punt te krijgen.

Het bouwen van de datastructuren zal tijd vergen, maar als het eenmaal gedaan is, en goed gedaan, kan het opzoeken en retourneren van een dataset in minder dan milliseconden worden gedaan (exclusief enige http- of off-box-communicatie van oorzaak)

Ik hoop dat dit helpt.



  1. Bulkupdates van Oracle met ODP.NET

  2. Oracle:Bottom-up verwijderen

  3. Waarden selecteren die aan verschillende voorwaarden voldoen op verschillende rijen?

  4. PostgreSQL:Hoe kom ik erachter dat er ontbrekende getallen in een kolom zijn met behulp van Genereer_series()?