Ladění výkonu dotazů pomocí služby Azure Cosmos DB

PLATÍ PRO: NoSQL

Azure Cosmos DB poskytuje rozhraní API pro NoSQL pro dotazování dat bez nutnosti schématu nebo sekundárních indexů. Tento článek obsahuje následující informace pro vývojáře:

  • Podrobné informace o tom, jak funguje spouštění dotazů SQL ve službě Azure Cosmos DB
  • Tipy a osvědčené postupy pro výkon dotazů
  • Příklady využití metrik spouštění dotazů SQL k ladění výkonu dotazů

Informace o spouštění dotazů SQL

Data ve službě Azure Cosmos DB jsou uložená v kontejnerech, což může růst na libovolnou velikost úložiště nebo propustnost požadavků. Azure Cosmos DB bezproblémově škáluje data napříč fyzickými oddíly v rámci krytů, aby zvládla růst dat nebo zvýšila zřízenou propustnost. Dotazy SQL můžete vydávat do libovolného kontejneru pomocí rozhraní REST API nebo některé z podporovaných sad SQL SDK.

Stručný přehled dělení: definujete klíč oddílu, například město, který určuje způsob rozdělení dat mezi fyzické oddíly. Data patřící do jednoho klíče oddílu (například "city" == "Seattle") se ukládají do fyzického oddílu a jeden fyzický oddíl může ukládat data z více klíčů oddílů. Když oddíl dosáhne limitu úložiště, služba bezproblémově rozdělí oddíl na dva nové oddíly. Data se rovnoměrně distribuují napříč novými oddíly a udržují všechna data pro jeden klíč oddílu pohromadě. Vzhledem k tomu, že oddíly jsou přechodné, rozhraní API používají abstrakci rozsahu klíčů oddílu, který označuje rozsahy hodnot hash klíče oddílu.

Když vydáte dotaz do služby Azure Cosmos DB, sada SDK provede tyto logické kroky:

  • Parsujte dotaz SQL a určete plán provádění dotazů.
  • Pokud dotaz obsahuje filtr pro klíč oddílu, například SELECT * FROM c WHERE c.city = "Seattle", je směrován do jednoho oddílu. Pokud dotaz nemá filtr pro klíč oddílu, spustí se ve všech oddílech a výsledky z každého oddílu se sloučí na straně klienta.
  • Dotaz se provádí v rámci každého oddílu v řadě nebo paralelně na základě konfigurace klienta. V rámci každého oddílu může dotaz provést jednu nebo více cest zaokrouhlení v závislosti na složitosti dotazu, nakonfigurované velikosti stránky a zřízené propustnosti kolekce. Každé spuštění vrátí počet jednotek žádostí spotřebovaných prováděním dotazů a statistikou provádění dotazů.
  • Sada SDK provádí souhrn výsledků dotazu napříč oddíly. Pokud například dotaz zahrnuje ORDER BY napříč oddíly, výsledky z jednotlivých oddílů se seřadí a vrátí výsledky v globálně seřazeném pořadí. Pokud je dotaz agregací, například COUNT, sečtou se počty z jednotlivých oddílů, aby se vytvořil celkový počet.

Sady SDK poskytují různé možnosti spouštění dotazů. Například v .NET jsou tyto možnosti k dispozici ve QueryRequestOptions třídě. Následující tabulka popisuje tyto možnosti a jejich vliv na dobu provádění dotazů.

Možnost Popis
EnableScanInQuery Platí pouze v případě, že je zakázáno indexování požadované cesty filtru. Pokud jste se odhlásili z indexování a chcete spouštět dotazy pomocí úplné kontroly, musí být nastavená na hodnotu True.
MaxItemCount Maximální počet položek, které se mají vrátit za zpáteční cestu na server. Můžete ho nastavit na hodnotu -1, aby server mohl spravovat počet položek, které se mají vrátit.
MaxBufferedItemCount Maximální počet položek, které lze během paralelního provádění dotazů ukládat do vyrovnávací paměti na straně klienta. Hodnota kladné vlastnosti omezuje počet položek vyrovnávací paměti na nastavenou hodnotu. Můžete ho nastavit na méně než 0, aby systém automaticky rozhodil počet položek, které se mají ukládat do vyrovnávací paměti.
MaxConcurrency Získá nebo nastaví počet souběžných operací spuštěných na straně klienta během paralelního provádění dotazů. Hodnota kladné vlastnosti omezuje počet souběžných operací na nastavenou hodnotu. Můžete ho nastavit na méně než 0, aby systém automaticky rozhodl počet souběžných operací, které se mají spustit.
PopulateIndexMetrics Umožňuje kolekci metrik indexů pochopit, jak dotazovací modul používal existující indexy a jak by mohl využívat potenciální nové indexy. Tato možnost způsobuje režii, takže by měla být povolená pouze při ladění pomalých dotazů.
ResponseContinuationTokenLimitInKb Maximální velikost tokenu pokračování vráceného serverem můžete omezit. Pokud má hostitel aplikace omezení velikosti hlavičky odpovědi, může to být potřeba nastavit, ale může zvýšit celkovou dobu trvání a spotřebované ru pro dotaz.

Tady je například dotaz na kontejner rozdělený pomocí /city sady .NET SDK:

QueryDefinition query = new QueryDefinition("SELECT * FROM c WHERE c.city = 'Seattle'");
QueryRequestOptions options = new QueryRequestOptions()
{
    MaxItemCount = -1,
    MaxBufferedItemCount = -1,
    MaxConcurrency = -1,
    PopulateIndexMetrics = true
};
FeedIterator<dynamic> feedIterator = container.GetItemQueryIterator<dynamic>(query);

FeedResponse<dynamic> feedResponse = await feedIterator.ReadNextAsync();

Každé spuštění dotazu odpovídá rozhraní REST API POST s hlavičkami nastavenými pro možnosti požadavku dotazu a dotaz SQL v textu. Podrobnosti o hlavičkách a možnostech požadavků REST API najdete v tématu Dotazování prostředků pomocí rozhraní REST API.

Osvědčené postupy pro výkon dotazů

Následující faktory obvykle mají největší vliv na výkon dotazů služby Azure Cosmos DB. V tomto článku se podrobněji podíváme na každý z těchto faktorů.

Faktor Tip
Zřízená propustnost Změřte ru na dotaz a ujistěte se, že máte požadovanou zřízenou propustnost pro vaše dotazy.
Dělení a klíče oddílů Upřednostňování dotazů s hodnotou klíče oddílu v klauzuli filtru pro nízkou latenci.
Možnosti sady SDK a dotazů Dodržujte osvědčené postupy sady SDK, jako je přímé připojení, a vylaďte možnosti spouštění dotazů na straně klienta.
Latence sítě Spusťte aplikaci ve stejné oblasti jako účet služby Azure Cosmos DB, kdykoli je to možné, abyste snížili latenci.
Zásady indexování Ujistěte se, že máte požadované cesty indexování nebo zásady pro dotaz.
Metriky spouštění dotazů Analyzujte metriky spouštění dotazů a identifikujte potenciální přepsání obrazců dotazů a dat.

Zřízená propustnost

Ve službě Azure Cosmos DB vytvoříte kontejnery dat, z nichž každá má rezervovanou propustnost vyjádřenou v jednotkách žádostí (RU) za sekundu. Čtení dokumentu o 1 kB je jedna RU a každá operace (včetně dotazů) se normalizuje na pevný počet RU na základě složitosti. Pokud máte například pro kontejner zřízených 1000 RU/s a máte dotaz podobný SELECT * FROM c WHERE c.city = 'Seattle' 5 RU, můžete spustit (1000 RU/s) / (5 RU/dotaz) = 200 těchto dotazů za sekundu.

Pokud odešlete více než 200 dotazů za sekundu (nebo některé jiné operace, které sytí všechny zřízené RU), služba spustí omezování rychlosti příchozích požadavků. Sady SDK automaticky zpracovávají omezování rychlosti provedením opakování a opakování, takže u těchto dotazů můžete zaznamenat vyšší latenci. Zvýšení zřízené propustnosti na požadovanou hodnotu zlepšuje latenci a propustnost dotazu.

Další informace o jednotkách žádostí najdete v tématu Jednotky žádosti.

Dělení a klíče oddílů

Ve službě Azure Cosmos DB jsou následující scénáře čtení dat seřazené od toho, co je obvykle nejrychlejší/nejúčinnější až po nejpomalejší/nejméně efektivní.

  • GET pro jeden klíč oddílu a ID položky, označované také jako čtení bodu
  • Dotazování pomocí klauzule filtru pro jeden klíč oddílu
  • Dotaz s klauzulí filtru rovnosti nebo rozsahu u libovolné vlastnosti
  • Dotaz bez filtrů

Dotazy, které je potřeba spouštět na všech oddílech, mají vyšší latenci a můžou využívat vyšší počet RU. Vzhledem k tomu, že každý oddíl má automatické indexování pro všechny vlastnosti, může být dotaz v tomto případě efektivně obsluhována z indexu. Dotazy, které pokrývají oddíly rychleji, můžete provádět pomocí možností paralelismu.

Další informace o dělení a klíčích oddílů najdete v tématu Dělení ve službě Azure Cosmos DB.

Možnosti sady SDK a dotazů

Podívejte se na tipy k výkonu dotazů a testování výkonu, které vám pomůžou dosáhnout nejlepšího výkonu na straně klienta ze služby Azure Cosmos DB pomocí našich sad SDK.

Latence sítě

Informace o tom, jak nastavit globální distribuci a připojit se k nejbližší oblasti, najdete v tématu globální distribuce služby Azure Cosmos DB. Latence sítě má významný vliv na výkon dotazů, když potřebujete provést několik odezv nebo načíst velkou sadu výsledků dotazu.

Metriky spouštění dotazů můžete použít k načtení doby provádění serveru dotazů, což vám umožní rozlišovat čas strávený při provádění dotazů od času stráveného při přenosu v síti.

Zásady indexování

Podívejte se na konfiguraci zásad indexování pro cesty, druhy a režimy indexování a vliv na provádění dotazů. Azure Cosmos DB ve výchozím nastavení aplikuje automatické indexování na všechna data a používá indexy rozsahu pro řetězce a čísla, což je efektivní pro dotazy na rovnost. U scénářů vložení s vysokým výkonem zvažte vyloučení cest ke snížení nákladů na RU pro každou operaci vložení.

Pomocí metrik indexu můžete zjistit, které indexy se používají pro každý dotaz, a pokud nějaké chybějící indexy, které by zlepšily výkon dotazů.

Metriky spouštění dotazů

Podrobné metriky se vrátí pro každé spuštění dotazu v diagnostice požadavku. Tyto metriky popisují čas strávený během provádění dotazů a umožňují pokročilé řešení potíží.

Přečtěte si další informace o získání metrik dotazů.

Metrika Unit Popis
TotalTime milisekundy Celková doba provádění dotazů
DocumentLoadTime milisekundy Čas strávený načítáním dokumentů
DocumentWriteTime milisekundy Čas strávený psaním a serializací výstupních dokumentů
IndexLookupTime milisekundy Čas strávený ve vrstvě fyzického indexu
QueryPreparationTime milisekundy Čas strávený přípravou dotazu
RuntimeExecutionTime milisekundy Celková doba provádění modulu runtime dotazu
VMExecutionTime milisekundy Čas strávený spuštěním dotazu za běhu dotazu
OutputDocumentCount count Počet výstupních dokumentů v sadě výsledků
OutputDocumentSize count Celková velikost výstupních dokumentů v bajtech
RetrievedDocumentCount count Celkový počet načtených dokumentů
RetrievedDocumentSize bajtů Celková velikost načtených dokumentů v bajtech
IndexHitRatio poměr [0,1] Poměr počtu dokumentů odpovídajících filtru k počtu načtených dokumentů

Klientské sady SDK můžou interně vytvářet více požadavků na dotazy, které budou obsluhovat dotaz v rámci každého oddílu. Pokud celkový počet výsledků překročí možnost žádosti o maximální počet položek, klient provede více než jedno volání na oddíl, pokud dotaz překročí zřízenou propustnost oddílu, pokud datová část dotazu dosáhne maximální velikosti na stránce nebo pokud dotaz dosáhne limitu časového limitu přiděleného systémem. Každé částečné spuštění dotazu vrátí metriky dotazu pro danou stránku.

Tady jsou některé ukázkové dotazy a jak interpretovat některé metriky vrácené z provádění dotazu:

Dotaz Ukázková metrika Popis
SELECT TOP 100 * FROM c "RetrievedDocumentCount": 101 Počet načtených dokumentů je 100+1 odpovídající klauzuli TOP. Čas dotazu je většinou strávený WriteOutputTime a DocumentLoadTime protože se jedná o kontrolu.
SELECT TOP 500 * FROM c "RetrievedDocumentCount": 501 Funkce RetrievedDocumentCount je teď vyšší (500+1, aby odpovídala klauzuli TOP).
SELECT * FROM c WHERE c.N = 55 "IndexLookupTime": "00:00:00.0009500" Přibližně 0,9 ms se stráví v IndexLookupTime pro vyhledání klíče, protože se jedná o vyhledávání indexu ./N/?
SELECT * FROM c WHERE c.N > 55 "IndexLookupTime": "00:00:00.0017700" Trochu více času (1,7 ms) stráveného v IndexLookupTime přes prohledávání rozsahu, protože se jedná o vyhledávání indexu ./N/?
SELECT TOP 500 c.N FROM c "IndexLookupTime": "00:00:00.0017700" Stejný čas strávený DocumentLoadTime s předchozími dotazy, ale nižší DocumentWriteTime , protože promítáme jenom jednu vlastnost.
SELECT TOP 500 udf.toPercent(c.N) FROM c "RuntimeExecutionTime": "00:00:00.2136500" Přibližně 213 ms je vynaloženo při RuntimeExecutionTime provádění UDF pro každou hodnotu .c.N
SELECT TOP 500 c.Name FROM c WHERE STARTSWITH(c.Name, 'Den') "IndexLookupTime": "00:00:00.0006400", "RuntimeExecutionTime": "00:00:00.0074100" Asi 0,6 ms je stráven na IndexLookupTime/Name/?. Většina času provádění dotazu (~7 ms) v RuntimeExecutionTime.
SELECT TOP 500 c.Name FROM c WHERE STARTSWITH(LOWER(c.Name), 'den') "IndexLookupTime": "00:00:00", "RetrievedDocumentCount": 2491, "OutputDocumentCount": 500 Dotaz se provádí jako kontrola, protože používá LOWERa vrátí se 500 z 2491 načtených dokumentů.

Další kroky

  • Další informace o podporovaných operátorech dotazů SQL a klíčových slovech najdete v dotazu SQL.
  • Další informace o jednotkách žádostí najdete v tématu Jednotky žádostí.
  • Další informace o zásadách indexování najdete v tématu Zásady indexování.