Översikt över spatiala index
gäller för:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceSQL-databas i Microsoft Fabric
SQL Server stöder rumsliga data och rumsliga index. Ett rumsligt index är en typ av utökat index som gör att du kan indexera en rumslig kolumn. En rumslig kolumn är en tabellkolumn som innehåller data av en rumslig datatyp, till exempel geometri eller geografi.
Tips
SQL Server spatial tools är en Microsoft-sponsrad samling verktyg med öppen källkod för användning med rumsliga typer i SQL Server. Det här projektet innehåller en uppsättning återanvändbara funktioner som program kan använda. Dessa funktioner kan omfatta datakonverteringsrutiner, nya transformeringar, aggregeringar osv. Mer information finns i Microsoft/SQLServerSpatialTools i GitHub.
Om spatiala index
Dela upp indexerat utrymme i en rutnätshierarki
I SQL Server skapas rumsliga index med B-träd, vilket innebär att indexen måste representera tvådimensionella rumsliga data i linjär ordning i B-träd. Innan du läser data i ett rumsligt index implementerar SQL Server därför en hierarkisk enhetlig nedbrytning av utrymme. Processen för att skapa index dela upp utrymmet i en rutnätshierarki på fyra nivåer. Dessa nivåer kallas nivå 1 (den översta nivån), nivå 2, nivå 3och nivå 4.
Varje efterföljande nivå delar vidare upp nivån ovanför den, så varje cell på den övre nivån innehåller ett fullständigt rutnät på nästa nivå. På en viss nivå har alla rutnät samma antal celler längs båda axlarna (till exempel 4x4 eller 8x8), och cellerna är alla en storlek.
Följande bild visar nedbrytningen för den övre högra cellen på varje nivå i rutnätshierarkin i ett 4x4-rutnät. I verkligheten är alla celler sönderdelade på detta sätt. Till exempel ger nedbrytning av ett utrymme i fyra nivåer av 4x4-rutnät faktiskt totalt 65 536 nivå-fyra celler.
Notera
Nedbrytningen av utrymme för ett rumsligt index är oberoende av den måttenhet som programdata använder.
Rutnätshierarkiceller numreras linjärt med hjälp av en variant av Hilberts utrymmesfyllningskurva. I illustrationssyfte använder dock den här diskussionen en enkel radvis numrering, i stället för numreringen som faktiskt produceras av Hilbert-kurvan. I följande bild har flera polygoner som representerar byggnader och linjer som representerar gator redan placerats i ett 4x4, nivå 1-rutnät. Nivå-1-cellerna numreras från 1 till 16, med början i den övre vänstra cellen.
Rutnätsdensitet
Antalet celler längs axlarna i ett rutnät avgör dess densitet: ju större tal, desto tätare rutnät. Till exempel är ett 8x8-rutnät (som producerar 64 celler) tätare än ett 4x4-rutnät (som producerar 16 celler). Rutnätsdensitet definieras per nivå.
Instruktionen CREATE SPATIAL INDEXTransact-SQL stöder en GRIDS-sats som gör att du kan ange olika rutnätstätheter på olika nivåer. Rutnätsdensiteten för en viss nivå anges med något av följande nyckelord.
Nyckelord | Rutnätskonfiguration | Antal celler |
---|---|---|
LÅG | 4X4 | 16 |
medel | 8X8 | 64 |
HÖG | 16X16 | 256 |
När databaskompatibilitetsnivån är inställd på 100 eller lägre i SQL Server är standardvärdet MEDIUM på alla nivåer. När databaskompatibilitetsnivån är inställd på 110 eller högre är standardinställningen ett automatiskt rutnätsschema. (Autorutnät anger en 8-nivåskonfiguration av HLLLLLLL.) I stället för varierande indexrutnätsdensitet kan du variera celler per objekt och fråga fönsterceller per objekt via tips.
Du kan styra nedbrytningsprocessen genom att ange rutnätstätheter som inte är standard. Till exempel kan olika rutnätstätheter på olika nivåer vara användbara för att finjustera ett index baserat på storleken på det indexerade utrymmet och objekten i den rumsliga kolumnen.
Notera
Rutnätstätheterna för ett rumsligt index visas i level_1_grid-, level_2_grid-, level_3_grid- och level_4_grid-kolumnerna i sys.spatial_index_tessellations katalogvyn när databaskompatibilitetsnivån är inställd på 100 eller lägre. Alternativen för tessellering-schema GEOMETRY_AUTO_GRID/GEOGRAPHY_AUTO_GRID fyller inte i dessa kolumner. sys.spatial_index_tessellations katalogvy har NULL värden för dessa kolumner när auto-rutnätsalternativ används.
Tessellering
Efter nedbrytningen av ett indexerat utrymme i en rutnätshierarki läser det rumsliga indexet data från den rumsliga kolumnen, rad för rad. När du har läst data för ett rumsligt objekt (eller en instans) utför det rumsliga indexet en tessellationsprocess för objektet. Tessellationsprocessen passar objektet i rutnätshierarkin genom att associera objektet med en uppsättning rutnätsceller som det berör (vidrörda celler). Från och med nivå 1 i rutnätshierarkin fortsätter tessellationsprocessen bredd först över nivån. Processen kan eventuellt fortsätta genom alla fyra nivåerna, en nivå i taget.
Utdata från tessellationsprocessen är en uppsättning touchade celler som registreras i objektets rumsliga index. Genom att referera till dessa registrerade celler kan det rumsliga indexet hitta objektet i rymden i förhållande till andra objekt i den rumsliga kolumnen som också lagras i indexet.
Tesselleringsregler
För att begränsa antalet vidrörda celler som registreras för ett objekt tillämpar tessellationsprocessen flera tessellationsregler. Dessa regler bestämmer djupet i tessellationsprocessen och vilka av de rörda cellerna som registreras i indexet.
Dessa regler är följande:
Täckningsregeln
Om objektet helt täcker en cell sägs cellen vara täckt av objektet. En täckt cell räknas och är inte tessellerad. Den här regeln gäller på alla nivåer i rutnätshierarkin. Den täckande regeln förenklar tessellationsprocessen och minskar mängden data som ett rumsligt index registrerar.
Regeln för celler per objekt
Den här regeln tillämpar gränsen på celler per objekt, som avgör det maximala antalet celler som kan räknas för varje objekt, med undantag för nivå 1. På lägre nivåer styr regeln cells-per-object mängden information som kan registreras om objektet.
Den djupaste cellregeln
Den djupaste cellregeln genererar den bästa uppskattningen av ett objekt genom att endast registrera de celler längst ned som har tessellerats för objektet. Överordnade celler bidrar inte till antalet celler per objekt och de registreras inte i indexet.
Dessa tessellationsregler tillämpas rekursivt på varje rutnätsnivå. I resten av det här avsnittet beskrivs tessellationsreglerna mer detaljerat.
Täckande regel
Om ett objekt helt täcker en cell sägs cellen vara täckt av objektet. I följande bild är till exempel en av cellerna på andra nivån, 15,11, helt täckt av mittendelen av en oktagon.
En täckt cell räknas och registreras i indexet och cellen tesselleras inte ytterligare.
Celler-Per-Object Regel
Omfattningen av tessellationen för varje objekt beror främst på cell-per-objekt-gränsen för det rumsliga indexet. Den här gränsen definierar det maximala antalet celler som tessellation kan räkna per objekt. Observera dock att regeln cells-per-object inte tillämpas för nivå 1, så det är möjligt att överskrida den här gränsen. Om antalet nivå-1 når eller överskrider gränsen för celler per objekt sker ingen ytterligare tessellation på de lägre nivåerna.
Så länge antalet är mindre än gränsen för celler per objekt fortsätter tessellationsprocessen. Från och med cellen med lägst antal vidrörda celler (till exempel cell 15,6 i föregående bild) testar processen varje cell för att utvärdera om den ska räknas eller tessellateras. Om tessellering av en cell skulle överskrida gränsen för celler per objekt, räknas cellen men tesselleras inte. Annars delas cellen upp i ett rutnät, och de celler på en lägre nivå som berörs av objektet räknas. Tessellationsprocessen fortsätter på det här sättet, breddmässigt, över hela nivån. Den här processen upprepas rekursivt för de nedre rutnäten i de tessellerade cellerna tills gränsen har nåtts eller så finns det inga fler celler att räkna.
Tänk till exempel på föregående bild, som visar en oktagon som passar helt in i cell 15 i rutnätet level-1. I figuren har cell 15 tessellerats, vilket har delat upp oktagonen i nio celler på nivå 2. Den här bilden förutsätter att gränsen för celler per objekt är 9 eller mer. Om cellgränsen per objekt var 8 eller mindre skulle cell 15 dock inte vara tessellerad, och endast cell 15 skulle räknas för objektet.
Som standard är gränsen för celler per objekt 16 celler per objekt, vilket ger en tillfredsställande kompromiss mellan utrymme och precision för de flesta rumsliga index. Instruktionen CREATE SPATIAL INDEXTransact-SQL stöder dock en CELLS_PER_OBJECT =n-sats som gör att du kan ange en cell-per-objektgräns mellan 1 och 8192, inklusive.
Notera
Inställningen cells_per_object för ett rumsligt index visas i sys.spatial_index_tessellations katalogvy.
Deepest-Cell-regel
Den djupaste cellregeln utnyttjar det faktum att varje cell på lägre nivå tillhör cellen ovanför den: en nivå-4-cell tillhör en nivå-3-cell, en nivå-3-cell tillhör en nivå-2-cell och en nivå-2-cell tillhör en nivå-1-cell. Ett objekt som till exempel tillhör cell 1.1.1.1 tillhör också cell 1.1.1, cell 1.1 och cell 1. Kunskap om sådana cellhierarkirelationer är inbyggda i frågeprocessorn. Därför behöver endast de djupaste cellerna registreras i indexet, vilket minimerar den information som indexet behöver lagra.
I illustrationen nedan är en relativt liten rombformad polygon tessellerad. Indexet använder standardgränsen för celler per objekt på 16, som inte nås för det här lilla objektet. Därför fortsätter tessellationen ned till nivå 4. Polygonen finns i följande nivå-1 genom nivå-3 celler: 4, 4.4 och 4.4.10 och 4.4.14. Men med den djupaste cellregeln räknar tessellationen endast de tolv nivå-4-cellerna: 4.4.10.13-15 och 4.4.14.1-3, 4.4.14.5-7 och 4.4.14.9-11.
Tessellation-scheman
Beteendet för ett rumsligt index beror delvis på dess tessellationsschema. Tessellationsschemat är datatypsspecifikt. I SQL Server stöder rumsliga index två tessellationsscheman:
geometrirutnäts tessellation, vilket är schemat för geometri datatyp.
geografiskt rutnätstessellering, som gäller för kolumner i geografi datatyp.
Notera
Inställningen tessellation_scheme för det rumsliga indexet visas i sys.spatial_index_tessellations katalogvyn.
Tessellationsschema för geometrirutnät
GEOMETRY_AUTO_GRID tessellation är standardschemat för tessellation för geometri datatyp för SQL Server 2012 (11.x) och senare. GEOMETRY_GRID tessellation är det enda tessellationsschemat som är tillgängligt för geometridatatyper i SQL Server 2008 (10.0.x). I det här avsnittet beskrivs aspekter av geometriskt rutnätstessellering som är relevanta för att arbeta med rumsliga index: stödda metoder och avgränsningsrutor.
Notera
Du kan uttryckligen ange det här tessellationsschemat med hjälp av instruktionen USING (GEOMETRY_AUTO_GRID/GEOMETRY_GRID) i instruktionen CREATE SPATIAL INDEX Transact-SQL.
Begränsningsram
Geometriska data upptar ett plan som kan vara oändligt. I SQL Server kräver dock ett rumsligt index ett begränsat utrymme. För att upprätta ett begränsat utrymme för nedbrytning kräver geometrirutnätets tessellationsschema ett rektangulärt avgränsningsruta. Avgränsningsrutan definieras av fyra koordinater, (x-min,y-min) och (x-max,y-max), som lagras som egenskaper för det rumsliga indexet. Dessa koordinater representerar följande:
x-min är x-koordinaten för avgränsningsrutans nedre vänstra hörn.
y-min är y-koordinaten i det nedre vänstra hörnet.
x-max är x-koordinaten för det övre högra hörnet.
y-max är y-koordinaten i det övre högra hörnet.
Anteckning
Dessa koordinater anges av instruktionen BOUNDING_BOX i instruktionen CREATE SPATIAL INDEXTransact-SQL.
Koordinaterna (x-min,y-min) och (x-max,y-max) koordinaterna bestämmer placeringen och dimensionerna för avgränsningsrutan. Utrymmet utanför avgränsningsrutan behandlas som en enda cell som är numrerad 0.
Det rumsliga indexet delar upp utrymmet inuti avgränsningsrutan. Nivå 1 av rutnäthierarkin fyller avgränsningsrutan. Om du vill placera ett geometriskt objekt i rutnätshierarkin jämför det rumsliga indexet koordinaterna för objektet med koordinaterna för avgränsningsrutan.
Följande bild visar punkterna som definieras av (x-min,y-min) och (x-max,y-max) koordinater för avgränsningsrutan. Den översta nivån i rutnätshierarkin visas som ett 4x4-rutnät. För illustrationen utelämnas de lägre nivåerna. Utrymmet utanför avgränsningsrutan anges med noll (0). Observera att objektet "A" delvis sträcker sig utanför rutan och att objektet "B" ligger helt utanför rutan i cell 0.
En avgränsningsruta motsvarar en del av ett programs rumsliga data. Om indexets avgränsningsruta helt innehåller data som lagras i den rumsliga kolumnen, eller bara innehåller en del, är upp till programmet. Endast åtgärder som beräknas på objekt som är helt inne i avgränsningsrutan drar nytta av det rumsliga indexet. För att få störst fördel av ett rumsligt index på en geometri kolumn måste du därför ange en avgränsningsruta som innehåller alla eller de flesta objekten.
Notis
Gittertätheterna för ett rumsligt index visas i kolumnerna bounding_box_xmin, bounding_box_ymin, bounding_box_xmax och bounding_box_ymax i sys.spatial_index_tessellations katalogvyn.
Geografirutnätets tessellationsschema
Det här tessellationsschemat gäller endast för en geografi kolumn. Det här avsnittet sammanfattar de metoder som stöds av tessellation för geografirutnät och beskriver hur geodetiskt utrymme projiceras på ett plan, som sedan delas upp i en rutnätshierarki.
Note
Du kan uttryckligen ange det här tessellationsschemat med hjälp av INSTRUKTIONEN USING (GEOGRAPHY_AUTO_GRID/GEOGRAPHY_GRID) i instruktionen CREATE SPATIAL INDEXTransact-SQL.
Projektion av geodetiska rymden på ett plan
Beräkningar på geografi instanser (objekt) behandlar utrymmet som innehåller objekten som en geodetisk ellipsoid. För att dela upp det här utrymmet delar tessellationsschemat för geografirutnät upp ytan på ellipsoiden i dess övre och nedre halvklot och utför sedan följande steg:
Projicerar varje halvklot på fasetter i en fyrsidig pyramid.
Plattar ut de två pyramiderna.
Sammanfogar de utplattade pyramiderna för att bilda ett icke-Euklidskt plan.
Följande bild visar en schematisk vy över nedbrytningsprocessen i tre steg. I pyramiderna representerar de streckade linjerna gränserna för de fyra fasetter i varje pyramid. Steg 1 och 2 illustrerar den geodetiska ellipsoiden med hjälp av en grön vågrät linje för att representera ekvatorial latitudlinjen och en serie gröna lodräta linjer som representerar flera longitudlinjer. Steg 1 visar pyramiderna som projiceras över de två halvkloten. Steg 2 visar pyramiderna som plattas ut. Steg 3 illustrerar de utplattade pyramiderna, efter att de har kombinerats för att bilda ett plan, som visar ett antal projicerade longitudlinjer. Observera att dessa planerade linjer rätas ut och varierar i längd, beroende på var de faller på pyramiderna.
När utrymmet har projicerats på planet delas planet upp i rutnätshierarkin på fyra nivåer. Olika nivåer kan använda olika rutnätstätheter. Följande bild visar planet efter att det har delats upp i ett rutnät på 4 x 4 nivå 1. I illustrationssyfte utelämnas de lägre nivåerna i rutnätshierarkin. I själva verket är planet helt sönderdelat i en rutnätshierarki på fyra nivåer. När nedbrytningsprocessen är klar läss geografiska data, rad för rad, från geografikolumnen och tessellationsprocessen utförs för varje objekt i tur och ordning.
Metoder som stöds av spatiala index
Geometrimetoder som stöds av spatiala index
Rumsliga index stöder följande uppsättningsorienterade geometrimetoder under vissa förhållanden: STContains(), STDistance(), STEquals(), STIntersects(), STOverlaps(), STTouches() och STWithin(). För att kunna stödjas av ett rumsligt index måste dessa metoder användas i WHERE- eller JOIN ON-satsen i en fråga, och de måste ske inom ett predikat i följande allmänna form:
geometri1.method_name(geometri2)comparison_operator**valid_number
För att returnera ett resultat som inte är null måste geometri1 och geometri2 ha samma spatial referensidentifierare (SRID). Annars returnerar metoden NULL.
Rumsliga index stöder följande predikatformulär:
geometri1.STContains(geometri2) = 1
geometri1.STDistance(geometri2) <nummer
geometri1.STDistance(geometri2) <= tal
geometri1.STEquals(geometri2)= 1
geometri1.STIntersects(geometri2)= 1
geometri1.STOverlaps(geometri2) = 1
geometri1.STTouches(geometri2) = 1
geometri1.STWithin(geometri2)= 1
Geografiska metoder som stöds av spatiala index
Under vissa förhållanden stöder rumsliga index följande uppsättningsorienterade geografiska metoder: STIntersects(),STEquals() och STDistance(). För att kunna stödjas av ett rumsligt index måste dessa metoder användas i WHERE-satsen för en fråga, och de måste ske inom ett predikat i följande allmänna form:
geografi1.method_name(geography2)comparison_operator**valid_number
Om du vill returnera ett resultat som inte är null måste geography1 och geography2 ha samma spatial referensidentifierare (SRID). Annars returnerar metoden NULL.
Rumsliga index stöder följande predikatformulär:
geografi1.STIntersects(geografi2)= 1
geografi1.STEquals(geografi2)= 1
geografi1.STDistance(geografi2) <nummer
geografi1.STDistance(geografi2) <= tal
Frågor som använder rumsliga index
Rumsliga index stöds endast i frågor som innehåller en indexerad rumslig operator i satsen WHERE. Till exempel syntax som:
[spatial object].SpatialMethod([reference spatial object]) [ = | < ] [const literal or variable]
Frågeoptimeraren förstår kommutativiteten för rumsliga operationer (som @a.STIntersects(@b) = @b.STIntersects(@a)
). Det rumsliga indexet används dock inte om början av en jämförelse inte innehåller den rumsliga operatorn (till exempel WHERE 1 = spatial op
inte använder det rumsliga indexet). Om du vill använda det rumsliga indexet skriver du om jämförelsen (till exempel WHERE spatial op = 1
).
Precis som med andra index, när ett rumsligt index stöds, väljs användningen av det rumsliga indexet baserat på kostnad, så frågeoptimeraren kanske inte väljer att använda det rumsliga indexet trots att alla krav för att använda det är uppfyllda. Använd showplan för att se om det rumsliga indexet användes och om det behövs ange frågetips för att tvinga fram en önskad frågeplan.
Den närmaste granntypen av frågan stöder också rumsliga index, men endast om en specifik frågesyntax skrivs. Lämplig syntax är:
SELECT TOP(K) [WITH TIES] *
FROM <Table> AS T [WITH(INDEX(<SpatialIndex>))]
WHERE <SpatialColumn>.STDistance(@reference_object) IS NOT NULL
ORDER BY <SpatialColumn>.STDistance(@reference_object) [;]