Indexeringsprinciper i Azure Cosmos DB
GÄLLER FÖR: NoSQL
I Azure Cosmos DB har varje container en indexeringspolicy som avgör hur containerns objekt ska indexeras. Standardprincipen för indexering för nyligen skapade containrar indexerar alla egenskaper för alla objekt och tillämpar intervallindex för alla strängar och tal. På så sätt kan du få goda frågeprestanda utan att behöva tänka på indexering eller indexhantering från början.
I vissa situationer kanske du vill åsidosätta det här automatiska beteendet för att bättre passa dina krav. Du kan anpassa en containers indexeringsprincip genom att ange dess indexeringsläge och inkludera eller exkludera egenskapssökvägar.
Anteckning
Metoden för att uppdatera indexeringsprinciper som beskrivs i den här artikeln gäller endast för Azure Cosmos DB API för NoSQL. Lär dig mer om indexering i Azure Cosmos DB API för MongoDB
Azure Cosmos DB stöder två indexeringslägen:
- Konsekvent: Indexet uppdateras synkront när du skapar, uppdaterar eller tar bort objekt. Det innebär att konsekvensen för dina läsfrågor är den konsekvens som konfigurerats för kontot.
- Ingen: Indexering är inaktiverat i containern. Det här läget används ofta när en container används som ett rent nyckelvärdeslager utan behov av sekundära index. Det kan också användas för att förbättra prestanda för massåtgärder. När massåtgärderna har slutförts kan indexläget ställas in på Konsekvent och sedan övervakas med hjälp av IndexTransformationProgress tills det är klart.
Anteckning
Azure Cosmos DB har också stöd för ett lazy-indexeringsläge. Lazy-indexering utför uppdateringar av indexet på en mycket lägre prioritetsnivå när motorn inte utför något annat arbete. Detta kan ge inkonsekventa eller ofullständiga frågeresultat. Om du planerar att köra frågor mot en Azure Cosmos DB-container bör du inte välja lat indexering. Nya containrar kan inte välja lat indexering. Du kan begära ett undantag genom att cosmosdbindexing@microsoft.com kontakta (förutom om du använder ett Azure Cosmos DB-konto i serverlöst läge som inte stöder lat indexering).
Som standard är indexeringsprincipen inställd på automatic
. Det uppnås genom att ange automatic
egenskapen i indexeringsprincipen till true
. Om du anger den här egenskapen till true
kan Azure Cosmos DB automatiskt indexera objekt när de skrivs.
I Azure Cosmos DB är den totala förbrukade lagringen kombinationen av både datastorleken och indexstorleken. Följande är några funktioner med indexstorlek:
- Indexstorleken beror på indexeringsprincipen. Om alla egenskaper indexeras kan indexstorleken vara större än datastorleken.
- När data tas bort komprimeras index nästan kontinuerligt. För små databorttagningar kanske du dock inte omedelbart ser en minskning av indexstorleken.
- Indexstorleken kan tillfälligt öka när fysiska partitioner delas. Indexutrymmet frigörs när partitionsdelningen har slutförts.
En anpassad indexeringsprincip kan ange egenskapssökvägar som uttryckligen ingår eller undantas från indexering. Genom att optimera antalet sökvägar som indexeras kan du avsevärt minska svarstiden och RU-kostnaden för skrivåtgärder. Dessa sökvägar definieras enligt den metod som beskrivs i avsnittet indexeringsöversikt med följande tillägg:
- en sökväg som leder till ett skalärt värde (sträng eller tal) slutar med
/?
- element från en matris åtgärdas tillsammans via notationen
/[]
(i stället för/0
,/1
osv.) - jokertecknet
/*
kan användas för att matcha alla element under noden
Tar samma exempel igen:
{
"locations": [
{ "country": "Germany", "city": "Berlin" },
{ "country": "France", "city": "Paris" }
],
"headquarters": { "country": "Belgium", "employees": 250 },
"exports": [
{ "city": "Moscow" },
{ "city": "Athens" }
]
}
sökvägen
headquarters
employees
är/headquarters/employees/?
sökvägen
locations
country
är/locations/[]/country/?
sökvägen till något under
headquarters
är/headquarters/*
Vi kan till exempel inkludera /headquarters/employees/?
sökvägen. Den här sökvägen skulle säkerställa att vi indexerade employees
egenskapen men inte indexerade extra kapslad JSON i den här egenskapen.
Alla indexeringsprinciper måste innehålla rotsökvägen /*
som antingen en inkluderad eller en exkluderad sökväg.
Inkludera rotsökvägen för att selektivt exkludera sökvägar som inte behöver indexeras. Den här metoden rekommenderas eftersom Azure Cosmos DB proaktivt kan indexera alla nya egenskaper som kan läggas till i din modell.
Exkludera rotsökvägen för att selektivt inkludera sökvägar som måste indexeras. Egenskapssökvägen för partitionsnyckeln indexeras inte som standard med uteslutningsstrategin och bör uttryckligen inkluderas om det behövs.
För sökvägar med vanliga tecken som inkluderar: alfanumeriska tecken och _ (understreck) behöver du inte fly från sökvägssträngen runt dubbla citattecken (till exempel "/path/?"). För sökvägar med andra specialtecken måste du undvika sökvägssträngen runt dubbla citattecken (till exempel "/"path-abc"/?"). Om du förväntar dig specialtecken i din väg kan du fly från alla vägar för säkerhet. Funktionellt gör det ingen skillnad om du flyr från varje sökväg eller bara de som har specialtecken.
Systemegenskapen
_etag
undantas som standard från indexering, såvida inte etag läggs till i den inkluderade sökvägen för indexering.Om indexeringsläget är inställt på konsekvent indexeras systemegenskaperna
id
och_ts
indexeras automatiskt.Om det inte finns någon explicit indexerad sökväg i ett objekt läggs ett värde till i indexet för att indikera att sökvägen är odefinierad.
Alla uttryckligen inkluderade sökvägar har värden som lagts till i indexet för varje objekt i containern, även om sökvägen är odefinierad för ett visst objekt.
Se det här avsnittet för indexering av principexempel för att inkludera och exkludera sökvägar.
Om dina inkluderade sökvägar och exkluderade sökvägar har en konflikt har den mer exakta sökvägen företräde.
Här är ett exempel:
Inkluderad sökväg: /food/ingredients/nutrition/*
Utesluten sökväg: /food/ingredients/*
I det här fallet har den inkluderade sökvägen företräde framför den exkluderade sökvägen eftersom den är mer exakt. Baserat på dessa sökvägar skulle alla data i food/ingredients
sökvägen eller kapslade inom undantas från indexet. Undantaget skulle vara data i den inkluderade sökvägen: /food/ingredients/nutrition/*
, som skulle indexeras.
Här följer några regler för inkluderade och exkluderade sökvägar i Azure Cosmos DB:
Djupare vägar är mer exakta än smalare vägar. till exempel:
/a/b/?
är mer exakt än/a/?
.Är
/?
mer exakt än/*
. Till exempel/a/?
är mer exakt än/a/*
så/a/?
har företräde.Sökvägen
/*
måste antingen vara en inkluderad sökväg eller en utesluten sökväg.
Anteckning
Du måste aktivera funktionen FullText och Hybrid Search for NoSQL API preview för att ange ett fulltextindex.
Fulltextindex möjliggör fulltextsökning och effektiv bedömning med hjälp av indexet. Det är enkelt att definiera en fullständig textsökväg i en indexeringsprincip genom att inkludera ett fullTextIndexes
avsnitt i indexeringsprincipen som innehåller alla textsökvägar som ska indexeras. Till exempel:
{
"indexingMode": "consistent",
"automatic": true,
"includedPaths": [
{
"path": "/*"
}
],
"excludedPaths": [
{
"path": "/\"_etag\"/?"
},
],
"fullTextIndexes": [
{
"path": "/text"
}
]
}
Viktigt
En fulltextindexeringsprincip måste finnas på den sökväg som definieras i containerns fulltextprincip. Läs mer om principer för containervektorer.
Anteckning
Du måste aktivera funktionen Azure Cosmos DB NoSQL Vector Search för att ange ett vektorindex.
Vektorindex ökar effektiviteten när du utför vektorsökningar med hjälp av VectorDistance
systemfunktionen. Vektorsökningar har lägre svarstid, högre dataflöde och mindre RU-förbrukning vid tillämpning av ett vektorindex. Du kan ange följande typer av vektorindexprinciper:
Typ | Beskrivning | Maximalt antal dimensioner |
---|---|---|
flat |
Lagrar vektorer i samma index som andra indexerade egenskaper. | 505 |
quantizedFlat |
Kvantifierar (komprimerar) vektorer innan de lagras i indexet. Detta kan förbättra svarstiden och dataflödet på bekostnad av en liten mängd noggrannhet. | 4096 |
diskANN |
Skapar ett index baserat på DiskANN för snabb och effektiv ungefärlig sökning. | 4096 |
Viktigt
För närvarande är vektorprinciper och vektorindex oföränderliga när de har skapats. Skapa en ny samling för att göra ändringar.
Några punkter att notera:
Indextyperna
flat
ochquantizedFlat
använder Azure Cosmos DB:s index för att lagra och läsa varje vektor när du utför en vektorsökning. Vektorsökningar med ettflat
index är råstyrkesökningar och ger 100 % noggrannhet eller återkallande. Det vill: det är garanterat att hitta de mest liknande vektorerna i datamängden. Det finns dock en begränsning av505
dimensioner för vektorer i ett platt index.Indexet
quantizedFlat
lagrar kvantiserade (komprimerade) vektorer i indexet. Vektorsökningar medquantizedFlat
index är också råstyrkesökningar, men deras noggrannhet kan vara något mindre än 100 % eftersom vektorerna kvantifieras innan de läggs till i indexet. Vektorsökningar medquantized flat
bör dock ha lägre svarstid, högre dataflöde och lägre RU-kostnad än vektorsökningar i ettflat
index. Det här är ett bra alternativ för scenarier där du använder frågefilter för att begränsa vektorsökningen till en relativt liten uppsättning vektorer, och hög noggrannhet krävs.Indexet
diskANN
är ett separat index som definierats specifikt för vektorer som tillämpar DiskANN, en uppsättning vektorindexeringsalgoritmer med höga prestanda som utvecklats av Microsoft Research. DiskANN-index kan erbjuda några av de lägsta svarstiderna, det högsta dataflödet och de lägsta RU-kostnadsfrågorna, samtidigt som hög noggrannhet bibehålls. Men eftersom DiskANN är ett ungefärligt närmsta grannindex (ANN) kan noggrannheten vara lägre änquantizedFlat
ellerflat
.
Indexen diskANN
och quantizedFlat
kan ta valfria indexgenereringsparametrar som kan användas för att justera noggrannheten jämfört med svarstidens kompromiss som gäller för varje ungefärligt vektorindex för närmaste grannar.
quantizationByteSize
: Anger storleken (i byte) för produktkvantisering. Min=1, Default=dynamic (systemet bestämmer), Max=512. Om du anger detta större kan det leda till högre precisionsvektorsökningar på bekostnad av högre RU-kostnader och högre svarstid. Detta gäller bådequantizedFlat
ochDiskANN
indextyper.indexingSearchListSize
: Anger hur många vektorer som ska sökas över under indexbygget. Min=10, Default=100, Max=500. Om du anger detta större kan det leda till högre noggrannhetsvektorsökningar på bekostnad av längre indexgenereringstider och högre svarstider för vektormatning. Detta gäller endast indexDiskANN
.
Här är ett exempel på en indexeringsprincip med ett vektorindex:
{
"indexingMode": "consistent",
"automatic": true,
"includedPaths": [
{
"path": "/*"
}
],
"excludedPaths": [
{
"path": "/_etag/?",
},
{
"path": "/vector/*"
}
],
"vectorIndexes": [
{
"path": "/vector",
"type": "diskANN"
}
]
}
Viktigt
En vektorindexeringsprincip måste finnas på den sökväg som definieras i containerns vektorprincip. Läs mer om principer för containervektorer.
Viktigt
Vektorsökvägen har lagts till i avsnittet "excludedPaths" i indexeringsprincipen för att säkerställa optimerad prestanda för infogning. Om du inte lägger till vektorsökvägen till "excludedPaths" resulterar det i högre RU-laddning och svarstid för vektorinfogningar.
När du definierar en rumslig sökväg i indexeringsprincipen bör du definiera vilket index type
som ska tillämpas på den sökvägen. Möjliga typer för rumsliga index är:
Punkt
Polygon
MultiPolygon
LineString
Azure Cosmos DB skapar som standard inga rumsliga index. Om du vill använda inbyggda funktioner för spatial SQL bör du skapa ett rumsligt index för de egenskaper som krävs. Se det här avsnittet för indexering av principexempel för att lägga till rumsliga index.
Tuppeln index är användbara när du utför filtrering på flera fält i ett matriselement. Tuppelns index definieras i avsnittet includedPaths i indexeringsprincipen med tuppelns specificerare "[]".
Anteckning
Till skillnad från inkluderade eller exkluderade sökvägar kan du inte skapa en sökväg med jokertecknet /* . Varje tupppelväg måste sluta med "/?". Om en tuppeln i en tuppelns sökväg inte finns i ett objekt läggs ett värde till i indexet för att indikera att tuppeln är odefinierad.
Matristupppelsökvägar definieras i avsnittet includedPaths och kommer att använda följande notation.
<path prefix>/[]/{<tuple 1>, <tuple 2> … <tuple n>}/?
Tänk på följande:
- Den första delen, sökvägsprefixet, är den sökväg som är gemensam mellan tupplar. Det är sökvägen från rot till matris. I vårt exempel är det "/events".
- Nästa är matrisens jokerteckensspecificerare "[]". Alla matristupppelsökvägar bör ha en jokerteckensspecificerare för matrisen före tuppelns specificerare "{}".
- Nästa är att ange tupplar med tuppelns specificerare "{}".
- Tupplar avgränsas med kommatecken.
- Tuppeln måste använda samma sökvägsspecifikation som andra indexsökvägar med några få undantag:
- Tupplar bör inte börja med inledande "/".
- Tupplar ska inte ha jokertecken i matrisen.
- Tupplar ska inte sluta "?" eller "*"
- “?” är det sista segmentet i en tuppelns sökväg och bör anges omedelbart efter tuppelns specificerarsegment.
Ett exempel:
/events/[]/{name, category}/?
Det här är några exempel på giltiga matristupplar:
“includedPaths”:[
{“path”: “/events/[]/{name/first, name/last}/?”},
{“path”: “/events/[]/{name/first, category}/?”},
{“path”: “/events/[]/{name/first, category/subcategory}/?”},
{“path”: “/events/[]/{name/[1]/first, category}/?”},
{“path”: “/events/[]/{[1], [3]}/?”},
{“path”: “/city/[1]/events/[]/{name, category}/?”}
]
Det här är några exempel på ogiltiga matristupplar
/events/[]/{name/[]/first, category}/?
- En av tupplar har matris jokertecken
/events/[]/{name, category}/*
- Det sista segmentet i matristuppelns sökväg ska vara "?" och inte *
/events/[]/{{name, first},category}/?
- Tuppelns specificerare är kapslad
/events/{name, category}/?
- Matrisens jokertecken saknas innan tuppelns specificerare
/events/[]/{/name,/category}/?
- Tupplar börjar med inledande
/
- Tupplar börjar med inledande
/events/[]/{name/?,category/?}/?
- Tupplar slutar med en
?
- Tupplar slutar med en
/city/[]/events/[]/{name, category}/?
- Sökvägsprefixet som 2 jokertecken i matrisen
Frågor som har en ORDER BY
sats med två eller flera egenskaper kräver ett sammansatt index. Du kan också definiera ett sammansatt index för att förbättra prestanda för många likhets- och intervallfrågor. Som standard definieras inga sammansatta index, så du bör lägga till sammansatta index efter behov.
Till skillnad från inkluderade eller exkluderade sökvägar kan du inte skapa en sökväg med /*
jokertecknet. Varje sammansatt sökväg har en implicit /?
i slutet av sökvägen som du inte behöver ange. Sammansatta sökvägar leder till ett skalärt värde som är det enda värdet som ingår i det sammansatta indexet. Om en sökväg i ett sammansatt index inte finns i ett objekt eller leder till ett icke-skalära värde läggs ett värde till i indexet för att indikera att sökvägen är odefinierad.
När du definierar ett sammansatt index anger du:
Två eller flera egenskapssökvägar. Sekvensen där egenskapssökvägar definieras spelar roll.
Ordningen (stigande eller fallande).
Anteckning
När du lägger till ett sammansatt index använder frågan befintliga intervallindex tills det nya sammansatta indextillägget har slutförts. När du lägger till ett sammansatt index kanske du därför inte omedelbart ser prestandaförbättringar. Du kan spåra förloppet för indextransformeringen med hjälp av en av SDK:erna.
Följande överväganden används när du använder sammansatta index för frågor med en ORDER BY
sats med två eller flera egenskaper.
Om de sammansatta indexsökvägarna inte matchar sekvensen för egenskaperna i
ORDER BY
-satsen kan det sammansatta indexet inte stödja frågan.Ordningen på sammansatta indexsökvägar (stigande eller fallande) bör också matcha
order
iORDER BY
-satsen.Det sammansatta indexet stöder också en
ORDER BY
sats med motsatt ordning på alla sökvägar.
Tänk dig följande exempel där ett sammansatt index definieras för egenskapers namn, ålder och _ts:
Sammansatt index | Exempelfråga ORDER BY |
Stöds av sammansatt index? |
---|---|---|
(name ASC, age ASC) |
SELECT * FROM c ORDER BY c.name ASC, c.age asc |
Yes |
(name ASC, age ASC) |
SELECT * FROM c ORDER BY c.age ASC, c.name asc |
No |
(name ASC, age ASC) |
SELECT * FROM c ORDER BY c.name DESC, c.age DESC |
Yes |
(name ASC, age ASC) |
SELECT * FROM c ORDER BY c.name ASC, c.age DESC |
No |
(name ASC, age ASC, timestamp ASC) |
SELECT * FROM c ORDER BY c.name ASC, c.age ASC, timestamp ASC |
Yes |
(name ASC, age ASC, timestamp ASC) |
SELECT * FROM c ORDER BY c.name ASC, c.age ASC |
No |
Du bör anpassa indexeringsprincipen så att du kan hantera alla nödvändiga ORDER BY
frågor.
Om en fråga har filter för två eller flera egenskaper kan det vara bra att skapa ett sammansatt index för dessa egenskaper.
Tänk till exempel på följande fråga som har både ett likhets- och intervallfilter:
SELECT *
FROM c
WHERE c.name = "John" AND c.age > 18
Den här frågan är effektivare, tar mindre tid och förbrukar färre RU:er om den kan använda ett sammansatt index på (name ASC, age ASC)
.
Frågor med flera intervallfilter kan också optimeras med ett sammansatt index. Varje enskilt sammansatt index kan dock bara optimera ett enda intervallfilter. Intervallfilter inkluderar >
, <
, <=
, >=
och !=
. Intervallfiltret ska definieras sist i det sammansatta indexet.
Överväg följande fråga med ett likhetsfilter och två intervallfilter:
SELECT *
FROM c
WHERE c.name = "John" AND c.age > 18 AND c._ts > 1612212188
Den här frågan är effektivare med ett sammansatt index på (name ASC, age ASC)
och (name ASC, _ts ASC)
. Frågan skulle dock inte använda ett sammansatt index på (age ASC, name ASC)
eftersom egenskaperna med likhetsfilter måste definieras först i det sammansatta indexet. Två separata sammansatta index krävs i stället för ett enda sammansatt index eftersom (name ASC, age ASC, _ts ASC)
varje sammansatt index bara kan optimera ett enda intervallfilter.
Följande överväganden används när du skapar sammansatta index för frågor med filter för flera egenskaper
- Filteruttryck kan använda flera sammansatta index.
- Egenskaperna i frågans filter ska matcha egenskaperna i det sammansatta indexet. Om en egenskap finns i det sammansatta indexet men inte ingår i frågan som ett filter använder frågan inte det sammansatta indexet.
- Om en fråga har andra egenskaper i filtret som inte definieras i ett sammansatt index används en kombination av sammansatta index och intervallindex för att utvärdera frågan. Detta kräver färre RU:er än att endast använda intervallindex.
- Om en egenskap har ett intervallfilter (
>
,<
,<=
,>=
eller!=
), bör den här egenskapen definieras sist i det sammansatta indexet. Om en fråga har fler än ett intervallfilter kan den dra nytta av flera sammansatta index. - När du skapar ett sammansatt index för att optimera frågor med flera filter påverkas
ORDER
inte resultatet av det sammansatta indexet. Den här egenskapen är valfri.
Tänk dig följande exempel där ett sammansatt index definieras för egenskapers namn, ålder och tidsstämpel:
Sammansatt index | Exempelfråga | Stöds av sammansatt index? |
---|---|---|
(name ASC, age ASC) |
SELECT * FROM c WHERE c.name = "John" AND c.age = 18 |
Yes |
(name ASC, age ASC) |
SELECT * FROM c WHERE c.name = "John" AND c.age > 18 |
Yes |
(name ASC, age ASC) |
SELECT COUNT(1) FROM c WHERE c.name = "John" AND c.age > 18 |
Yes |
(name DESC, age ASC) |
SELECT * FROM c WHERE c.name = "John" AND c.age > 18 |
Yes |
(name ASC, age ASC) |
SELECT * FROM c WHERE c.name != "John" AND c.age > 18 |
No |
(name ASC, age ASC, timestamp ASC) |
SELECT * FROM c WHERE c.name = "John" AND c.age = 18 AND c.timestamp > 123049923 |
Yes |
(name ASC, age ASC, timestamp ASC) |
SELECT * FROM c WHERE c.name = "John" AND c.age < 18 AND c.timestamp = 123049923 |
No |
(name ASC, age ASC) and (name ASC, timestamp ASC) |
SELECT * FROM c WHERE c.name = "John" AND c.age < 18 AND c.timestamp > 123049923 |
Yes |
Om en fråga filtrerar på en eller flera egenskaper och har olika egenskaper i ORDER BY-satsen kan det vara bra att lägga till egenskaperna i filtret ORDER BY
i -satsen.
Genom att till exempel lägga till egenskaperna i filtret i ORDER BY
-satsen kan följande fråga skrivas om för att tillämpa ett sammansatt index:
Fråga med intervallindex:
SELECT *
FROM c
WHERE c.name = "John"
ORDER BY c.timestamp
Fråga med sammansatt index:
SELECT *
FROM c
WHERE c.name = "John"
ORDER BY c.name, c.timestamp
Samma frågeoptimeringar kan generaliseras för alla ORDER BY
frågor med filter, med tanke på att enskilda sammansatta index endast kan stödja högst ett intervallfilter.
Fråga med intervallindex:
SELECT *
FROM c
WHERE c.name = "John" AND c.age = 18 AND c.timestamp > 1611947901
ORDER BY c.timestamp
Fråga med sammansatt index:
SELECT *
FROM c
WHERE c.name = "John" AND c.age = 18 AND c.timestamp > 1611947901
ORDER BY c.name, c.age, c.timestamp
Dessutom kan du använda sammansatta index för att optimera frågor med systemfunktioner och ORDER BY:
Fråga med intervallindex:
SELECT *
FROM c
WHERE c.firstName = "John" AND Contains(c.lastName, "Smith", true)
ORDER BY c.lastName
Fråga med sammansatt index:
SELECT *
FROM c
WHERE c.firstName = "John" AND Contains(c.lastName, "Smith", true)
ORDER BY c.firstName, c.lastName
Följande överväganden gäller när du skapar sammansatta index för att optimera en fråga med ett filter och ORDER BY
en sats:
- Om du inte definierar ett sammansatt index för en fråga med ett filter på en egenskap och en separat
ORDER BY
sats med en annan egenskap, kommer frågan fortfarande att lyckas. RU-kostnaden för frågan kan dock minskas med ett sammansatt index, särskilt om egenskapen iORDER BY
satsen har hög kardinalitet. - Om frågan filtrerar efter egenskaper bör dessa egenskaper inkluderas först i
ORDER BY
-satsen. - Om frågan filtrerar på flera egenskaper måste likhetsfiltren vara de första egenskaperna i
ORDER BY
-satsen. - Om frågan filtrerar på flera egenskaper kan du ha högst ett intervallfilter eller en systemfunktion som används per sammansatt index. Egenskapen som används i intervallfiltret eller systemfunktionen ska definieras sist i det sammansatta indexet.
- Alla överväganden för att skapa sammansatta index för
ORDER BY
frågor med flera egenskaper och frågor med filter på flera egenskaper gäller fortfarande.
Sammansatt index | Exempelfråga ORDER BY |
Stöds av sammansatt index? |
---|---|---|
(name ASC, timestamp ASC) |
SELECT * FROM c WHERE c.name = "John" ORDER BY c.name ASC, c.timestamp ASC |
Yes |
(name ASC, timestamp ASC) |
SELECT * FROM c WHERE c.name = "John" AND c.timestamp > 1589840355 ORDER BY c.name ASC, c.timestamp ASC |
Yes |
(timestamp ASC, name ASC) |
SELECT * FROM c WHERE c.timestamp > 1589840355 AND c.name = "John" ORDER BY c.timestamp ASC, c.name ASC |
No |
(name ASC, timestamp ASC) |
SELECT * FROM c WHERE c.name = "John" ORDER BY c.timestamp ASC, c.name ASC |
No |
(name ASC, timestamp ASC) |
SELECT * FROM c WHERE c.name = "John" ORDER BY c.timestamp ASC |
No |
(age ASC, name ASC, timestamp ASC) |
SELECT * FROM c WHERE c.age = 18 and c.name = "John" ORDER BY c.age ASC, c.name ASC,c.timestamp ASC |
Yes |
(age ASC, name ASC, timestamp ASC) |
SELECT * FROM c WHERE c.age = 18 and c.name = "John" ORDER BY c.timestamp ASC |
No |
Om en fråga filtrerar på en eller flera egenskaper och har en aggregerad systemfunktion kan det vara bra att skapa ett sammansatt index för egenskaperna i filter- och aggregerade systemfunktionen. Den här optimeringen gäller för sum- och AVG-systemfunktionerna .
Följande överväganden gäller när du skapar sammansatta index för att optimera en fråga med en filter- och aggregerad systemfunktion.
- Sammansatta index är valfria när du kör frågor med aggregeringar. RU-kostnaden för frågan kan dock ofta minskas med ett sammansatt index.
- Om frågan filtrerar på flera egenskaper måste likhetsfiltren vara de första egenskaperna i det sammansatta indexet.
- Du kan ha högst ett intervallfilter per sammansatt index och det måste finnas på egenskapen i den aggregerade systemfunktionen.
- Egenskapen i den aggregerade systemfunktionen ska definieras sist i det sammansatta indexet.
- (
order
ASC
ellerDESC
) spelar ingen roll.
Sammansatt index | Exempelfråga | Stöds av sammansatt index? |
---|---|---|
(name ASC, timestamp ASC) |
SELECT AVG(c.timestamp) FROM c WHERE c.name = "John" |
Yes |
(timestamp ASC, name ASC) |
SELECT AVG(c.timestamp) FROM c WHERE c.name = "John" |
No |
(name ASC, timestamp ASC) |
SELECT AVG(c.timestamp) FROM c WHERE c.name > "John" |
No |
(name ASC, age ASC, timestamp ASC) |
SELECT AVG(c.timestamp) FROM c WHERE c.name = "John" AND c.age = 25 |
Yes |
(age ASC, timestamp ASC) |
SELECT AVG(c.timestamp) FROM c WHERE c.name = "John" AND c.age > 25 |
No |
Nedan visas ett exempel på ett sammansatt index som innehåller ett jokertecken för matrisen.
{
"automatic":true,
"indexingMode":"Consistent",
"includedPaths":[
{
"path":"/*"
}
],
"excludedPaths":[],
"compositeIndexes":[
[
{"path":"/familyname", "order":"ascending"},
{"path":"/children/[]/age", "order":"descending"}
]
]
}
En exempelfråga som kan dra nytta av det här sammansatta indexet är:
SELECT r.id
FROM root r
JOIN ch IN r.children
WHERE r.familyname = 'Anderson' AND ch.age > 20
En containers indexeringsprincip kan uppdateras när som helst med hjälp av Azure Portal eller någon av de SDK:er som stöds. En uppdatering av indexeringsprincipen utlöser en transformering från det gamla indexet till det nya, som utförs online och på plats (så inget extra lagringsutrymme förbrukas under åtgärden). Den gamla indexeringsprincipen omvandlas effektivt till den nya principen utan att påverka skrivtillgängligheten, lästillgängligheten eller dataflödet som etablerats i containern. Indextransformeringen är en asynkron åtgärd och den tid det tar att slutföra beror på det etablerade dataflödet, antalet objekt och deras storlek. Om flera indexeringsprincipuppdateringar måste göras rekommenderar vi att du gör alla ändringar som en enda åtgärd för att indextransformeringen ska slutföras så snabbt som möjligt.
Viktigt
Indextransformering är en åtgärd som förbrukar enheter för begäran och uppdatering av indexprincipen är en RU-bunden åtgärd. Om någon indexeringsterm missas ser kunden frågor som förbrukar mer övergripande RU:er.
Anteckning
Du kan spåra förloppet för indextransformeringen i Azure Portal eller med hjälp av någon av SDK:erna.
Skrivtillgängligheten påverkas inte under indextransformeringar. Indextransformeringen använder dina etablerade RU:er men med lägre prioritet än crud-åtgärder eller frågor.
Lästillgängligheten påverkas inte när nya indexerade sökvägar läggs till. Frågor använder bara nya indexerade sökvägar när en indextransformering är klar. När du lägger till en ny indexerad sökväg har med andra ord frågor som drar nytta av den indexerade sökvägen samma prestanda före och under indextransformeringen. När indextransformeringen är klar börjar frågemotorn använda de nya indexerade sökvägarna.
När du tar bort indexerade sökvägar bör du gruppera alla dina ändringar i en indexeringsprincipomvandling. Om du tar bort flera index och gör det i en enda ändring av indexeringsprincipen ger frågemotorn konsekventa och fullständiga resultat under indextransformeringen. Men om du tar bort index via flera indexeringsprincipändringar ger frågemotorn inte konsekventa eller fullständiga resultat förrän alla indextransformeringar har slutförts. De flesta utvecklare släpper inte index och försöker sedan omedelbart köra frågor som använder dessa index, så i praktiken är den här situationen osannolik.
När du släpper en indexerad sökväg slutar frågemotorn omedelbart att använda den och gör en fullständig genomsökning i stället.
Anteckning
Om möjligt bör du alltid försöka gruppera flera indexborttagningar i en enda ändring av indexeringsprincipen.
Viktigt
Att ta bort ett index börjar gälla omedelbart, medan det tar lite tid att lägga till ett nytt index eftersom det kräver en indexeringstransformering. När du ersätter ett index med ett annat (till exempel ersätta ett enskilt egenskapsindex med ett sammansatt index) måste du lägga till det nya indexet först och sedan vänta tills indextransformeringen har slutförts innan du tar bort det tidigare indexet från indexeringsprincipen. Annars påverkar detta din möjlighet att fråga det tidigare indexet negativt och kan bryta alla aktiva arbetsbelastningar som refererar till det tidigare indexet.
Användning av TTL-funktionen (Time-to-Live) kräver indexering. Detta innebär att:
- det går inte att aktivera TTL på en container där indexeringsläget är inställt på
none
, - Det går inte att ange indexeringsläget till Ingen på en container där TTL är aktiverat.
För scenarier där ingen egenskapssökväg behöver indexeras, men TTL krävs, kan du använda en indexeringsprincip med indexeringsläget inställt på consistent
, inga inkluderade sökvägar och /*
som den enda undantagna sökvägen.