Pokyny k dotazům OData Analytics pro Azure DevOps

Azure DevOps Services | Azure DevOps Server 2022 – Azure DevOps Server 2019

Vývojáři rozšíření můžou těžit podle pokynů uvedených v tomto článku pro navrhování efektivních dotazů OData pro Analytics pro Azure DevOps. Následující pokyny pomáhají zajistit, aby dotazy měly dobrý výkon pro dobu provádění a spotřebu prostředků. Dotazy, které nedodržují tyto pokyny, můžou mít za následek nízký výkon s dlouhými dobami čekání na sestavu, dotazy, které překračují povolenou spotřebu prostředků nebo blokování služeb.

Poznámka:

Služba Analytics je automaticky povolená a podporovaná v produkčním prostředí pro všechny služby Azure DevOps Services. Integrace Power BI a přístup k datovému kanálu OData služby Analytics jsou obecně dostupné. Doporučujeme, abyste ho používali a poskytli nám zpětnou vazbu. Dostupná data jsou závislá na verzi. Nejnovější podporovaná verze je v2.0a nejnovější verze Preview je v4.0-preview. Další informace najdete v tématu Správa verzí rozhraní API OData.

Poznámka:

Služba Analytics se automaticky nainstaluje a podporuje v produkčním prostředí pro všechny nové kolekce projektů pro Azure DevOps Server 2020 a novější verze. Integrace Power BI a přístup k datovému kanálu OData služby Analytics jsou obecně dostupné. Doporučujeme, abyste ho používali a poskytli nám zpětnou vazbu. Pokud jste upgradovali z Azure DevOps Serveru 2019, můžete během upgradu nainstalovat službu Analytics.

Dostupná data jsou závislá na verzi. Nejnovější podporovaná verze je v2.0a nejnovější verze Preview je v4.0-preview. Další informace najdete v tématu Správa verzí rozhraní API OData.

Poznámka:

Služba Analytics je ve verzi Preview pro Azure DevOps Server 2019. Můžete ji povolit nebo nainstalovat pro kolekci projektů. Integrace Power BI a přístup k datovému kanálu OData služby Analytics jsou ve verzi Preview. Doporučujeme, abyste ho používali a poskytli nám zpětnou vazbu.

Dostupná data jsou závislá na verzi. Nejnovější podporovaná verze je v2.0a nejnovější verze Preview je v4.0-preview. Další informace najdete v tématu Správa verzí rozhraní API OData.

Tyto pokyny jsou naše doporučení s předponou TERMÍNY DO, ZVAŽTE, VYHNĚTE SE A NE. Omezující pravidla vynucená službou Analytics obsahují předponu [BLOCKED]. Měli byste pochopit kompromisy mezi různými řešeními. Za určitých okolností můžete mít požadavky na data, které vás přinutí porušení jednoho nebo více pokynů. Takové případy by měly být vzácné. Doporučujeme, abyste měli jasný a přesvědčivý důvod pro taková rozhodnutí.

Tip

Příklady uvedené v tomto dokumentu jsou založené na adrese URL služby Azure DevOps Services. Použijte náhrady pro místní verze.

https://{servername}:{port}/tfs/{OrganizationName}/{ProjectName}/_odata/{version}/

Chybové a varovné zprávy

✔️ Do review OData response warnings

Každý dotaz, který provedete, se zkontroluje proti sadě předdefinovaných pravidel. Porušení vrací odpověď OData následující @vsts.warnings. Projděte si tato upozornění, protože poskytují aktuální a kontextově citlivé informace o tom, jak vylepšit dotaz.

{
  "@odata.context": "https://{OrganizationName}.tfsallin.net/_odata/v1.0/$metadata#WorkItems",
  "@vsts.warnings": [
    "The specified query does not include a $select or $apply clause which is recommended for all queries."
  ],
  ...
}

✔️ Kontrola chybových zpráv OData

Dotazy, které porušují pravidlo chyby OData, způsobí neúspěšnou odpověď se stavovým kódem 400 (Chybný požadavek). Přidružit @vsts.warnings zprávy se ve vlastnosti nezobrazí. Místo toho vygenerují chybovou message zprávu ve vlastnosti v odpovědi JSON.

{
  "error": {
  "code": "0",
  "message": "The query specified in the URI is not valid. The Snapshot tables in Analytics are intended to be used only in an aggregation."
  }
}

Omezení

Do's

Doporučujeme zvážit

Blokované

Vyhnutí se

✔️ Omezte dotaz na projekty, ke kterým máte přístup

Pokud dotaz cílí na data z projektu, ke kterým nemáte přístup, vrátí dotaz zprávu o odepření přístupu k projektu. Abyste měli jistotu, že máte přístup, ujistěte se, že je oprávnění Zobrazit analýzy nastavené na Povolit pro všechny projekty, na které dotazujete. Další informace najdete v tématu Oprávnění potřebná pro přístup k Analýzám.

Pokud nemáte přístup k projektu, zobrazí se následující zpráva:

Výsledky dotazu zahrnují data v jednom nebo více projektech, ke kterým nemáte přístup. Přidejte jeden nebo více filtrů projektů pro určení projektů, ke kterým máte přístup v entitě WorkItems. Pokud používáte $expand nebo navigační vlastnosti, je pro tyto entity vyžadován filtr projektu.

Pokud chcete tento problém obejít, můžete buď explicitně přidat filtr projektu, nebo použít koncový bod s vymezeným projektem, jak je vysvětleno dále v tomto článku.

Například následující dotaz načte pracovní položky, které patří do projektů pojmenovaných {projectSK1} a {projectSK2}.

https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
  $filter=ProjectSK eq {projectSK1} or ProjectSK eq {projectSK2}
  &$select=WorkItemId, Title

✔️ Do specify project filter inside the $expand clause if your expand could include data in other, potentially inaccessible projects

Když rozbalíte navigační vlastnosti, je možné, že budete odkazovat na data z jiných nepřístupných projektů. Pokud odkazujete na nepřístupná data, zobrazí se stejná chybová zpráva uvedená dříve: "Výsledky dotazu zahrnují data v jednom nebo více projektech...". Podobně můžete tento problém vyřešit přidáním explicitních filtrů projektu pro řízení rozbalených dat.

Můžete to udělat v regulární $filter klauzuli pro jednoduché navigační vlastnosti. Například následující dotaz explicitně požádá WorkItemLinks o umístění odkazu i cíle ve stejném projektu.

https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItemLinks?
  $filter=ProjectSK eq {projectSK} and TargetWorkItem/ProjectSK eq {projectSK}
  &$select=LinkTypeReferenceName, SourceWorkItemId, TargetWorkItemId
  &$expand=TargetWorkItem($select=WorkItemId, Title)

Místo toho můžete filtr přesunout a $filter rozbalit možnost v klauzuli $expand . Změní se ale sémantika dotazu. Například následující dotaz získá všechny odkazy z daného projektu a podmíněně rozšíří cíl pouze v případě, že existuje ve stejném projektu. I když je tento přístup platný, může to způsobit nejasnosti, protože může být obtížné určit, jestli není vlastnost rozbalována, protože je null nebo protože byla vyfiltrována. Toto řešení použijte pouze v případě, že toto konkrétní chování skutečně potřebujete.

https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItemLinks?
  $filter=ProjectSK eq {projectSK}
  &$select=LinkTypeReferenceName, SourceWorkItemId, TargetWorkItemId
  &$expand=TargetWorkItem($filter=ProjectSK eq {projectSK}; $select=WorkItemId, Title)

Možnost $filter rozbalení je užitečná, když použijete vlastnost rozbalení kolekce, například Children v WorkItems sadě entit. Následující dotaz například vrátí všechny pracovní položky z daného projektu společně se všemi podřízenými položkami, které patří do stejného projektu.

https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
  $filter=ProjectSK eq {projectSK}
  &$select=WorkItemId, Title
  &$expand=Children($filter=ProjectSK eq {projectSK}; $select=WorkItemId, Title)

Pokud rozbalíte jednu z následujících vlastností, zadejte filtr:

  • WorkItems sada entit: Parent, Children
  • WorkItemLinks sada entit: TargetWorkItem.

✔️ ZVAŽTE dotazování pomocí koncového bodu s vymezeným projektem.

Pokud vás zajímají data z jednoho projektu, doporučujeme použít koncový bod OData v oboru projektu (/{ProjectName}/_odata/v1.0). Vyhne se problémům popsaným v předchozích dvou částech a implicitně filtruje data na jeden projekt, sadu odkazovaných entit a všechny rozbalené navigační vlastnosti.

S tímto zjednodušením lze dotazy z předchozí části přepsat na následující formulář. Filtr v klauzuli rozbalení nejen zmizel, ale také není nutné filtrovat v hlavní sadě entit.

https://analytics.dev.azure.com/{OrganizationName}/{ProjectName}/_odata/{version}//WorkItemLinks?
  &$select=LinkTypeReferenceName, SourceWorkItemId, TargetWorkItemId
  &$expand=TargetWorkItem($select=WorkItemId, Title)

Dotaz na podřízené pracovní položky je také mnohem kratší a jednodušší.

https://analytics.dev.azure.com/{OrganizationName}/{ProjectName}/_odata/{version}//WorkItems?
  &$select=WorkItemId, Title
  &$expand=Children($select=WorkItemId, Title)

Toto řešení můžete použít pouze v případě, že se fokus týká dat z jednoho projektu. Pro generování sestav mezi projekty musíte použít strategie filtrování popsané v předchozích částech.

✔️ Počkejte nebo zastavte operaci, pokud dotaz překročí limity využití

Pokud spouštíte mnoho dotazů nebo dotazy vyžadují mnoho prostředků ke spuštění, můžete překročit limity služeb a dočasně zablokovat. Pokud překročíte limity služby, zastavte operaci, protože je pravděpodobné, že další dotaz, který odešlete, selže se stejnou chybovou zprávou.

Žádost byla zablokována kvůli překročení využití prostředku {resource} v oboru názvů {namespace}.

Další informace o omezování rychlosti najdete v tématu Omezení rychlosti. Informace o návrhu efektivních dotazů OData najdete v pokynech k výkonu dále v tomto článku.

✔️ Počkejte nebo zastavte operaci, pokud váš dotaz selže s vypršením časového limitu

Podobně jako překročení limitů využití byste měli počkat nebo zastavit operaci, pokud váš dotaz překročí časový limit. Může signalizovat přechodný problém, takže zkuste to znovu, abyste zjistili, jestli se problém vyřeší. Trvalé vypršení časového limitu však značí, že dotaz je pravděpodobně příliš nákladný ke spuštění. Další pokusy o opakování vedou pouze k překročení limitů využití a dojde k zablokování.

TF400733: Žádost byla zrušena: Žádost překročila časový limit požadavku, zkuste to prosím znovu.

Vypršení časových limitů značí, že dotaz vyžaduje optimalizaci. Informace o návrhu efektivních dotazů OData najdete v pokynech k výkonu dále v tomto článku.

❌ [BLOKOVÁNO] Nepoužívejte entity snímků pro nic jiného než pro agregace.

Sady entit snímků s příponou Snapshot jsou speciální, protože se modelují jako denní snímky. Pomocí nich můžete získat stav entit tak, jak byly na konci každého dne v minulosti. Pokud jste například dotazovali a vyfiltrovali WorkItemSnapshot jeden WorkItemIdzáznam , získáte jeden záznam pro každý den od vytvoření pracovní položky. Přímé načtení všech těchto dat by bylo nákladné a s největší pravděpodobností by překročilo limity využití a zablokovalo se. Agregace těchto entit jsou ale povolené i doporučené. Ve skutečnosti byly sady entit snímků navrženy s ohledem na scénáře agregace.

Například následující dotaz získá počet pracovních položek podle data a zjistí, jak se v lednu 2020 zvýšil.

https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItemSnapshot?
  $apply=
    filter(DateSK ge 20200101 and DateSK le 20200131)/
    groupby((DateSK), aggregate($count as Count))

Další informace o agregaci najdete v tématu Agregace dat.

✔️ Do include DateSK or DateValue column in groupby clause when you aggregate over snapshot tables

Vzhledem k tomu, že všechny entity snímků se modelují jako denní tabulky snímků, měli byste vždy zahrnout jednu z vlastností dne (DateSK nebo DateValue) do klauzule seskupení. Jinak se výsledek může zobrazit nesprávně nafukovaný.

Pokud jste například seskupili pouze AssignedTo podle vlastnosti a agregovali WorkItemSnapshot ho s počtem, vynásobí se počet pracovních položek přiřazených lidem počtem dní, kdy bylo každé přiřazení aktivní. I když může dojít k situaci, kdy se jedná o požadovaný výsledek, jsou takové případy vzácné.

❌ [BLOKOVÁNO] Nepoužívejte klíče entit v cestách prostředků k adresování entit.

Syntaxe OData poskytuje způsob, jak získat přístup ke konkrétní entitě tak, že zahrne jeho klíče přímo do segmentů adresy URL. Další informace najdete v tématu OData verze 4.0. Část 2: Konvence adres URL - 4.3 Adresování entit. I když OData takové adresování umožňuje, Analýza ho blokuje. Zahrnutí do dotazu má za následek následující chybu.

Dotaz zadaný v identifikátoru URI není platný. Analýza nepodporuje navigaci mezi klíči nebo vlastnostmi, jako je WorkItems(Id) nebo WorkItem(Id)/AssignedTo. Pokud se v Power BI zobrazí tato chyba, přepište dotaz, abyste se vyhnuli nesprávnému posouvání, které způsobuje problém N+1.

Vzhledem k tomu, že chybové zprávy naznačují, můžou určité klientské nástroje zneužít přímé adresování entit. Místo načtení všech dat v jednom požadavku se tito klienti mohou rozhodnout dotazovat se na každou entitu nezávisle. Tento postup se nedoporučuje, protože může vést k velkému počtu požadavků. Místo toho doporučujeme použít explicitní adresování entit, jak je vysvětleno v následující části.

✔️ DO explicitně adresovat entity pomocí klauzulí filtru

Pokud chcete načíst data pro jednu entitu, měli byste použít stejný přístup jako pro kolekci entit a explicitně definovat filtry v $filter klauzuli.

Například následující dotaz získá jednu pracovní položku podle identifikátoru.

https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
  $filter=WorkItemId eq {id}
  &$select=WorkItemId, Title

Pokud si nejste jistí, které vlastnosti byste měli do takového filtru zahrnout, můžete ho vyhledat v metadatech. Viz Vytváření dotazů OData pro analýzu, komponenty adresy URL pro dotazování metadat. Vlastnosti jsou v Key elementu EntityType. Jedná se například WorkItemIdRevision o klíčové sloupce entity WorkItemRevision .

<EntityType Name="WorkItemRevision">
  <Key>
    <PropertyRef Name="WorkItemId"/>
    <PropertyRef Name="Revision"/>
  </Key>
  [...]
</EntityType>

❌[BLOKOVÁNO] Nerozbalit Revisions entitu WorkItem

Datový model Analýza nepovoluje určité typy rozšíření. Jednou z nich, která může být pro některé překvapivá, je Revisions vlastnost kolekce entity WorkItem . Pokud se pokusíte tuto vlastnost rozbalit, zobrazí se následující chybová zpráva.

Dotaz zadaný v identifikátoru URI není platný. Vlastnost Revisions nelze použít v možnosti dotazu $expand.

Toto omezení bylo zavedeno tak, aby všichni používali doporučené řešení, které načítá revize WorkItemRevisions , jak je vysvětleno v následující části.

✔️ Do use WorkItemRevisions entity set to load all the revisions for a given work item

Použijte WorkItemRevisions pokaždé, když chcete načíst úplnou historii pracovní položky nebo kolekce pracovních položek.

Například následující dotaz vrátí všechny revize pracovní položky s identifikátorem {id} .

https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItemRevisions?
  $filter=WorkItemId eq {id}
  &$select=WorkItemId, Title

Pokud vás zajímá úplná historie všech pracovních položek, které odpovídají určitým kritériím, použijte filtr pro WorkItem navigační vlastnost. Například následující dotaz získá všechny revize všech aktuálně aktivních pracovních položek.

https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItemRevisions?
  $filter=WorkItem/State eq 'Active'
  &$select=WorkItemId, Title

❌ [BLOKOVÁNO] SESKUPOVAT U jedinečných sloupců

Pomocí operace seskupení můžete snížit počet záznamů. Použití jedinečných sloupců v groupby klauzuli značí problém a dotaz okamžitě selže. V případě náhodného výskytu této situace se zobrazí následující chybová zpráva.

Jeden nebo více sloupců zadaných v klauzuli groupby tohoto dotazu se nedoporučuje.

Pokud chcete tento problém vyřešit, odeberte z klauzule odlišný sloupec groupby .

❌ [BLOKOVÁNO] Nepoužívat countdistinct agregaci

Analýza funkci nepodporuje countdistinct , i když to dělá OData. I když plánujeme přidat podporu v budoucnu, momentálně není dostupná. Dotaz, který obsahuje tuto funkci, vrátí následující chybovou zprávu.

Dotazy, které používají počet jedinečných s agregací, se nepodporují.

❌ VYHNĚTE se agregacím, které můžou vést k aritmetickému přetečení

Ve výjimečných případech může agregační dotaz narazit na problémy s aritmetickým přetečením. Může k tomu dojít například v případě, že sčítáte některé číselné vlastnosti, které nejsou určené pro sčítání, například StackRank v entitách pracovní položky. Vzhledem k tomu, že rozšíření OData pro standard agregace dat neposkytuje způsob, jak přetypovat vlastnost na jiný typ, jediným způsobem, jak tento problém vyřešit, je odebrat problematickou vlastnost z agregace.

✔️ Použití dávkového koncového bodu pro dlouhé dotazy

S dlouhými dotazy můžete mít problémy. K problémům může dojít zejména v případě:

  • Dotazujete se na projekt s mnoha vlastními poli.
  • Váš dotaz se konstruuje programově.

Aktuální limit dotazů OData odeslaných pomocí HTTP GET 3 000 znaků. Pokud ho překročíte, vrátí se odpověď 404 Nenalezena.

HTTP/1.1 404 Not Found
Content-Length: 0

Pokud chcete tento problém vyřešit, použijte koncový bod dávky OData, jak je vysvětleno ve specifikaci OData verze 4.0. Část 1: Protokol - 11.7 Dávkové požadavky. Funkce Batch byla primárně navržena tak, aby seskupila více operací do datové části jedné HTTP žádosti, ale můžete ji použít také jako alternativní řešení pro omezení délky dotazu. Odesláním HTTP POST požadavku můžete předat dotaz libovolné délky a služba ji správně interpretuje.

❌ [BLOKOVÁNO] Nepoužívejte k odesílání více dotazů dávkového koncového bodu.

Použití dávkového koncového bodu omezujeme na zpracování dávky více požadavků. Jeden požadavek může mít stále jenom jeden dotaz. Pokud se pokusíte odeslat dávku několika dotazů, operace selže s následující chybovou zprávou. Jediným řešením je rozdělit dotazy na více požadavků.

Analýza nepodporuje zpracování více operací, které aktuální dávková zpráva obsahuje. Analýza k podpoře požadavků POST používá dávku OData, ale vyžaduje, abyste operaci omezili na jeden požadavek.

❌ [BLOKOVÁNO] Nepoužívejte dotazy, které vedou k více než 800 sloupcům.

Omezujeme dotazy, které vedou k více než 800 sloupcům. Pokud nejste dostatečně selektivní, ve kterých sloupcích dotaz vrátí, může se zobrazit následující chybová zpráva.

VS403670: Zadaný dotaz vrátí sloupce N, které jsou vyšší než povolený limit 800 sloupců. Pokud chcete omezit počet sloupců, použijte explicitní $select (včetně možností $expand).

Přidejte do dotazu klauzuli $select a $expand operací v dotazu, abyste se vyhnuli překročení tohoto limitu.

❌ Vyhněte se vytváření dlouhých dotazů

Doporučujeme, abyste svůj přístup vyhodnotili pokaždé, když vytvoříte dlouhý dotaz. I když existuje mnoho scénářů, které potřebují dlouhý dotaz (například komplexní filtry nebo dlouhý seznam vlastností), obvykle poskytují počáteční indikátor neoptimálního návrhu.

Pokud dotaz obsahuje v dotazu mnoho klíčů entit (například WorkItemId eq {id 1} or WorkItemId eq {id 2} or ...), můžete ho pravděpodobně přepsat. Místo předání identifikátorů se pokuste definovat některá další kritéria, která vyberou stejnou sadu entit. Někdy může být potřeba upravit proces (například přidat nové pole nebo značku), ale obvykle za to stojí. Dotazy, které používají abstraktivnější filtry, se snadněji udržují a mají větší potenciál pro lepší práci.

Dalším scénářem, který má tendenci generovat dlouhé dotazy, nastane, když zahrnete mnoho jednotlivých kalendářních dat (například DateSK eq {dateSK 1} or DateSK eq {dateSK 2} or ...). Vyhledejte jiný vzor, který můžete použít k vytvoření abstraktivnějšího filtru. Například následující dotaz vrátí všechny pracovní položky vytvořené v pondělí.

https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
  $filter=CreatedOn/DayOfWeek eq 2
  &$select=WorkItemId, Title, State

✔️ Zadejte časové pásmo při filtrování sloupců kalendářních dat

Časové pásmo (Edm.DateTimeOffset) zveřejňuje všechny informace o datu a čase s posunem, který odpovídá nastavení časového pásma organizace. Tato data jsou přesná a jednoduchá pro interpretaci ve stejnou dobu. Dalším neposlušným důsledkem je, že všechny filtry musí předávat také informace o časovém pásmu. Pokud ho přeskočíte, zobrazí se následující chybová zpráva.

Dotaz zadaný v identifikátoru URI není platný. Nebyl zadán žádný posun data a času. Pomocí některého z těchto formátů YYYYY-MM-ddZ zadejte vše od půlnoci nebo yyyy-MM-ddThh:mm-hh:mm (standardní reprezentace dat a časů ISO 8601) a určete posun.

Chcete-li tento problém vyřešit, přidejte informace o časovém pásmu. Předpokládejme například, že je organizace nakonfigurovaná tak, aby zobrazovala data v časovém pásmu (UTC-08:00) Pacific Time (USA a Kanada), následující dotaz získá všechny pracovní položky vytvořené od začátku roku 2020.

https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
  $filter=CreatedDate ge 2020-01-01T00:00:00-08:00
  &$select=WorkItemId, Title, State

Stejné řešení funguje pro časová pásma s kladnými posuny, ale znak plus (+) má v identifikátoru URI zvláštní význam a musíte ho zpracovat správně. Pokud jako výchozí bod zadáte 2020-01-01T00:00:00+08:00 (se znakem + ), zobrazí se následující chyba.

Dotaz zadaný v identifikátoru URI není platný. Syntaktická chyba na pozici 31 v 'CreatedDate ge 2020-01-01T0000 08:00'.

Chcete-li jej vyřešit, nahraďte + znak zakódovanou verzí , %2B. Předpokládejme například, že je organizace nakonfigurovaná tak, aby zobrazovala data v časovém pásmu "(UTC+08:00) Peking, Čchung-čching, Hongkong, Urumqi", následující dotaz vrátí všechny pracovní položky vytvořené od začátku roku 2020.

https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
  $filter=CreatedDate ge 2020-01-01T00:00:00%2B08:00
  &$select=WorkItemId, Title, State

Alternativním přístupem je použití vlastností náhradního klíče kalendářního data, protože neuchovávají informace o časovém pásmu. Následující dotaz například vrátí všechny pracovní položky vytvořené od začátku roku 2020 bez ohledu na nastavení organizace.

https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
  $filter=CreatedDateSK ge 20200101
  &$select=WorkItemId, Title, State

Pokyny k výkonu

Do's

Don't's

Doporučujeme zvážit

Vyhnutí se

✔️ DO změří účinek implementace pokynů k výkonu

Stejně jako u jakýchkoli doporučení k výkonu byste je neměli implementovat nevidomě. Místo toho vždy zachyťte směrný plán a změřte účinek provedených změn. Všechny pokyny byly vytvořeny na základě interakcí s klienty analýz, kteří měli specifické požadavky a výzvy. Tato doporučení byla považována za obecná a potenciálně užitečná pro každého, kdo navrhuje podobné dotazy. Ve výjimečných případech však použití pokynů nemůže mít žádný vliv nebo dokonce negativní vliv na výkon. Je potřeba změřit rozdíl, abyste si ho všimli. Pokud k tomu dojde, poskytněte nám zpětnou vazbu na portálu komunity vývojářů.

Existuje mnoho možností měření výkonu. Nejjednodušší je spustit dvě verze stejného dotazu přímo v prohlížeči. Sledujte čas potřebný k nástrojům pro vývojáře. Můžete například použít panel Sítě v Microsoft Edgi F12 Developer Tools). Další možností je zachytit tyto informace pomocí nástroje Fiddler Web Debugger.

Ať je váš přístup jakýkoliv, spusťte oba dotazy několikrát. Například 30krát spusťte dotazy, aby měly dostatečně velkou ukázkovou sadu. Pak zjistěte charakteristiky výkonu. Analýza se řídí architekturou s více tenanty. Další operace, ke kterým dochází současně, tedy můžou ovlivnit dobu trvání dotazů.

✔️ Do use aggregation extensions

Zdaleka nejlepší možností, jak zlepšit výkon dotazů, je použít rozšíření agregace – rozšíření OData pro agregaci dat. S rozšířením agregace požádejte službu, aby sumarizuje datovou stránku na straně serveru a vrátila menší odpověď, než jakou můžete načíst použitím stejné funkce na straně klienta. Analýza je nakonec optimalizovaná pro tento typ dotazů, takže ho využijte.

Další informace najdete v tématu Agregace dat.

✔️ Do specify columns in the $select clause

Zadejte sloupce, o které vám v klauzuli $select záleží. Analýza je založená na technologii Columnstore Index . To znamená, že data jsou úložiště i zpracování dotazů založená na sloupcích. Snížením sady vlastností můžete odkazovat v $select klauzuli, abyste snížili počet sloupců, které je potřeba zkontrolovat, a zlepšit celkový výkon dotazu.

Například následující dotaz určuje sloupce pro pracovní položky.

https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
  $select=WorkItemId, Title, State

Poznámka:

Azure DevOps podporuje přizpůsobení procesů. Někteří správci tuto funkci používají a vytvářejí stovky vlastních polí. Pokud klauzuli $select vynecháte, dotaz vrátí všechna pole včetně vlastních polí.

✔️ Do specify columns in the $select expand option inside the $expand clause

Podobně jako pokyny k klauzuli $select zadejte vlastnosti v možnosti rozbalení v $select rámci $expand klauzule. Je snadné zapomenout, ale pokud ji vynecháte, vaše odpověď obsahuje všechny vlastnosti z rozbaleného objektu.

Například následující dotaz určuje sloupce pro pracovní položku i její nadřazenou položku.

https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
  $select=WorkItemId, Title, State
  &$expand=Parent($select=WorkItemId, Title, State)

✔️ DO definujte filtr při dotazování RevisedDateSK na data historických pracovních položek (WorkItemRevisions nebo WorkItemSnapshot sad entit).

Při dotazování na historická data je pravděpodobné, že vás zajímá poslední období (například 30 dní, 90 dní). Vzhledem k tomu, jak se implementují entity pracovních položek, je vhodné psát takové dotazy, abyste získali skvělý výkon. Pokaždé, když aktualizujete pracovní položku, vytvoří novou revizi a zaznamená tuto akci do System.RevisedDate pole, což je ideální pro filtry historie.

V Analytics se upravené datum zobrazuje ve vlastnostech RevisedDate (Edm.DateTimeOffset) a RevisedDateSK (Edm.Int32). Nejlepšího výkonu dosáhnete tak, že použijete ten druhý. Jedná se o náhradní klíč data a představuje datum vytvoření revize nebo jeho null aktivní neúplné revize. Pokud chcete mít všechna data od inkluzivního {startDate} formátu, přidejte do dotazu následující filtr.

RevisedDateSK eq null or RevisedDateSK gt {startDateSK}

Například následující dotaz vrátí počet pracovních položek pro každý den od začátku roku 2020. Všimněte si, že kromě zřejmého filtru ve DateSK sloupci je druhý filtr .RevisedDateSK I když se může zdát redundantní, pomůže dotazovacímu stroji vyfiltrovat revize, které nejsou v oboru, a výrazně zvyšuje výkon dotazů.

https://analytics.dev.azure.com/{OrganizationName}/_odata/v1.0/WorkItemSnapshot?
  $apply=
    filter(DateSK gt 20200101)/
    filter(RevisedDateSK eq null or RevisedDateSK gt 20200101)/
    groupby(
      (DateValue), 
      aggregate($count as Count)
    )

Poznámka:

Přišli jsme s tímto doporučením, když jsme pracovali na widgetech Burndown. Zpočátku jsme definovali jenom filtry, DateSK ale tento dotaz se nám nepodařilo dobře škálovat pro organizace s velkými datovými sadami. Během profilace dotazů jsme si všimli, že DateSK nefiltruje dobře revize. Až po přidání filtru RevisedDateSK jsme mohli dosáhnout skvělého výkonu ve velkém měřítku.
~ Produktový tým

✔️ Používejte týdenní nebo měsíční snímky pro dotazy trendu, které trvají dlouhou dobu.

Ve výchozím nastavení se všechny tabulky snímků modelují jako tabulky faktů s denním snímkem. Pokud zadáte dotaz na časový rozsah, získá hodnotu pro každý den. Dlouhé časové rozsahy vedou k velkému počtu záznamů. Pokud takovou vysokou přesnost nepotřebujete, můžete použít týdenní nebo dokonce měsíční snímky.

Můžete to udělat s jinými výrazy filtru, abyste odebrali dny, které nedokončí daný týden nebo měsíc. IsLastDayOfPeriod Použijte vlastnost, která byla přidána do Analýzy s ohledem na tento scénář. Tato vlastnost je typu Microsoft.VisualStudio.Services.Analytics.Model.Period a může určit, jestli se den dokončí v různých obdobích (například týdny, měsíce atd.).

<EnumType Name="Period" IsFlags="true">
  <Member Name="None" Value="0"/>
  <Member Name="Day" Value="1"/>
  <Member Name="WeekEndingOnSunday" Value="2"/>
  <Member Name="WeekEndingOnMonday" Value="4"/>
  <Member Name="WeekEndingOnTuesday" Value="8"/>
  <Member Name="WeekEndingOnWednesday" Value="16"/>
  <Member Name="WeekEndingOnThursday" Value="32"/>
  <Member Name="WeekEndingOnFriday" Value="64"/>
  <Member Name="WeekEndingOnSaturday" Value="128"/>
  <Member Name="Month" Value="256"/>
  <Member Name="Quarter" Value="512"/>
  <Member Name="Year" Value="1024"/>
  <Member Name="All" Value="2047"/>
</EnumType>

Vzhledem k tomu Microsoft.VisualStudio.Services.Analytics.Model.Period , že je definován jako výčet s příznaky, použijte operátor OData has a zadejte úplný typ pro literály období.

IsLastDayOfPeriod has Microsoft.VisualStudio.Services.Analytics.Model.Period'Month'

Následující dotaz například vrátí počet pracovních položek, které byly definovány v posledním dni každého měsíce.

https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItemSnapshot?
  $apply=
    filter(IsLastDayOfPeriod has Microsoft.VisualStudio.Services.Analytics.Model.Period'Month')/
    groupby(
      (DateValue), 
      aggregate($count as Count)
    )

✔️ Při filtrování podle značek použijte Tags vlastnost kolekce u pracovních položek.

Vlastnost contains s funkcí můžete použít TagNames k určení, jestli byla práce označena konkrétní značkou. Tento přístup ale může vést k pomalým dotazům, zejména při kontrole více značek najednou. Pokud chcete dosáhnout nejlepšího výkonu Tags a výsledků, použijte místo toho navigační vlastnost.

Například následující dotaz získá všechny pracovní položky označené značkou {tag}.

https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
  $filter=Tags/any(t:t/TagName eq '{tag}')
  &$select=WorkItemId, Title, State

Tento přístup také funguje skvěle, když potřebujete filtrovat podle více značek. Následující dotaz například vrátí všechny pracovní položky, které byly označené {tag1}nebo{tag2}

https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
  $filter=Tags/any(t:t/TagName eq {tag1} or t/TagName eq {tag2})
  &$select=WorkItemId, Title, State

Tyto filtry můžete také kombinovat s operátorem "and". Například následující dotaz získá všechny pracovní položky označené oběma {tag1}a{tag2}

https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
  $filter=Tags/any(t:t/TagName eq {tag1}) and Tags/any(t:t/TagName eq {tag2})
  &$select=WorkItemId, Title, State

✔️ Do use TagNames property if you want to display all tags on a work item as text

Navigační vlastnost Tagspopsaná v předchozí části je skvělá pro filtrování. Práce s nimi ale představuje určité výzvy, protože dotaz vrací značky v vnořené kolekci. Datový model obsahuje TagNames také primitivní vlastnost (Edm.String), kterou jsme přidali ke zjednodušení scénářů spotřeby značek. Jedná se o jednu textovou hodnotu, která obsahuje seznam všech značek v kombinaci s oddělovačem středníku ;; . Tuto vlastnost použijte v případě, že se značky zobrazují společně. Můžete ho kombinovat s filtry značek popsanými výše.

Například následující dotaz získá všechny pracovní položky označené značkou {tag}. Vrátí ID, název, stav a textovou reprezentaci kombinovaných značek.

https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
  $filter=Tags/any(t:t/TagName eq '{tag}')
  &$select=WorkItemId, Title, State, TagNames

Důležité

Vlastnost TagNames má limit délky 1024 znaků. Obsahuje sadu značek, které se vejdou do tohoto limitu. Pokud má pracovní položka mnoho značek nebo jsou značky velmi dlouhé, TagNames nepoužívejte úplnou sadu a Tag navigační vlastnost by se měla použít.

❌ Nepoužívejte tolower a toupper funkce k porovnání nerozlišují malá a velká písmena

Pokud jste pracovali s jinými systémy, můžete očekávat, že použijete tolowertoupper funkce pro porovnání bez rozlišování malých a velkých písmen. Při analýze jsou všechna porovnání řetězců ve výchozím nastavení nerozlišována malá a velká písmena, takže pro explicitní zpracování nemusíte použít žádné funkce.

Například následující dotaz získá všechny pracovní položky označené jako "KVALITA", "kvalita" nebo jakoukoli jinou kombinaci tohoto slova.

https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
  $filter=Tags/any(t:t/TagName eq 'quality')
  &$select=WorkItemId, Title, State, TagNames

❌ Nepoužívat nevázané rozšíření s $levels=max

OData má možnost rozšířit všechny úrovně hierarchické struktury. Sledování pracovních položek má například některé entity, ve kterých je možné použít nevázané rozšíření. Tato operace funguje jenom pro organizace s malým množstvím dat. Není dobře škálovat pro větší datové sady. Nepoužívejte ho vůbec, pokud:

  • Pracujete s velkými datovými sadami.
  • Vyvíjíte widget a nemáte žádnou kontrolu nad tím, kde se widget nainstaluje.

✔️ Do use server-driven paging

Pokud se zeptáte na sadu, která je příliš velká, aby se odeslala v jedné odpovědi, analýza použije stránkování. Odpověď obsahuje pouze částečnou sadu a odkaz, který umožňuje načíst další částečnou sadu položek. Tato strategie je popsaná ve specifikaci OData – OData verze 4.0. Část 1: Protokol – stránkování řízené serverem Tím, že necháte službu řídit stránkování, získáte nejlepší výkon, protože skiptoken byla pečlivě navržena pro každou entitu co nejefektivnější.

Odkaz na další stránku je součástí @odata.nextLink vlastnosti.

{
  "@odata.context": "https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/$metadata#WorkItems(*)",
  "value": [
    ...
  ],
  "@odata.nextLink":"https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?$skiptoken=12345"}

Poznámka:

Většina stávajících klientů OData dokáže automaticky zpracovat stránkování řízené serverem. Například tuto strategii už používají následující nástroje: Power BI, SQL Server Integration Services a Azure Data Factory.

❌ Nepoužívat $top možnosti dotazů $skip k implementaci stránkování řízeného klientem

U jiných rozhraní REST API jste možná implementovali stránkování řízené klientem a $top$skip možnosti dotazů. Nepoužívejte je s Analýzou. Existuje několik problémů s tímto přístupem a výkon je jedním z nich. Místo toho přijměte strategii stránkování řízenou serverem popsanou v předchozí části.

✔️ Použití $top možnosti dotazu k omezení počtu záznamů

Možnost $top dotazu se nedoporučuje používat pouze při použití společně s parametrem $skip. Pokud ve scénáři vytváření sestav potřebujete jenom podmnožinu záznamů (například ukázku), je vhodné použít $top možnost dotazu. Pokud navíc potřebujete zařadit záznamy podle určitých kritérií, měli byste vždy použít $top kombinaci $orderby s cílem získat stabilní výsledek s nejlépe seřazenými záznamy.

✔️ ZVAŽTE napsání dotazu pro vrácení malého počtu záznamů.

Psaní dotazu pro vrácení malého počtu záznamů je nejtuitivnějším vodítkem. Vždy se snažte načíst jenom data, která vám opravdu záleží. Toho dosáhnete tak, že většinu výkonných možností filtrování zpřístupníte v dotazovacím jazyce OData.

✔️ ZVAŽTE omezení počtu vybraných vlastností na minimum.

Někteří správci projektů výrazně přizpůsobí své procesy přidáním vlastních polí. Velké přizpůsobení může vést k problémům s výkonem při načítání všech dostupných sloupců u širokých entit (například WorkItems). Analýza je založená na technologii Columnstore Index . To znamená, že data jsou úložiště i zpracování dotazů založená na sloupcích. Čím více vlastností dotaz odkazuje, tím dražší je zpracování. Vždy se snažte omezit sadu vlastností ve vašich dotazech na to, co vás ve scénáři vytváření sestav opravdu zajímá.

✔️ ZVAŽTE filtrování podle vlastností náhradního klíče data (DateSK přípona)

Existuje mnoho způsobů, jak definovat filtr kalendářních dat. Vlastnost data můžete filtrovat přímo (například CreatedDate), její navigační protějšek (například CreatedOnDate) nebo náhradní reprezentaci klíče (například CreatedDate). Poslední možnost přináší nejlepší výkon a je upřednostňovaná, když to požadavky na vytváření sestav umožňují.

Například následující dotaz získá všechny pracovní položky vytvořené od začátku roku 2020.

https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
  $filter=CreatedDateSK ge 20200101

✔️ ZVAŽTE filtrování podle náhradních klíčových sloupců

Pokud chcete filtrovat data o hodnotě souvisejícího objektu (například filtrování pracovní položky podle názvu projektu), máte vždy dvě možnosti. Můžete použít navigační vlastnost (například Project/ProjectName) nebo zachytit náhradní klíč předem a použít ho přímo v dotazu (například ProjectSK).

Pokud vytváříte widget, doporučujeme použít druhou možnost. Když se klíč předá jako součást dotazu, sníží se počet sad entit, které se musí dotýkat, a výkon se zlepší.

Například následující filtry WorkItems dotazu používají ProjectSK vlastnost místo Project/ProjectName navigační vlastnosti.

https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
  $filter=ProjectSK eq {projectSK}

❌ VYHNĚTE se použití Parent, Childrennebo Revisions vlastností v $filter klauzulích nebo $expand klauzulích

Pracovní položky jsou nejnákladnější entity v celém datovém modelu. Mají několik navigačních vlastností, které můžete použít pro přístup ke souvisejícím pracovním položkám: Parent, Children, Revisions. Pokaždé, když je použijete v dotazu, ale očekáváte pokles výkonu. Vždy se dotazujte, jestli opravdu potřebujete některou z těchto vlastností, a případně aktualizujte návrh.

Například místo rozbalení Parentmůžete načíst více pracovních položek a použít ParentWorkItemId vlastnost k rekonstrukci úplné hierarchie na straně klienta. Proveďte tuto optimalizaci na základě případu.

✔️ ZVAŽTE předání VSTS.Analytics.MaxSize předvoleb v hlavičce.

Při spuštění dotazu neznáte počet záznamů, které dotaz vrátí. Buď odešlete jiný dotaz s agregacemi, nebo postupujte podle všech dalších odkazů a načtěte celou datovou sadu. Analýza respektuje předvolbu VSTS.Analytics.MaxSize , která vám umožní rychle selhat v těchto instancích, že datová sada je větší než to, co může klient přijmout.

Tato možnost je užitečná ve scénářích exportu dat. Pokud ho chcete použít, musíte do požadavku HTTP přidat Prefer hlavičku a nastavit VSTS.Analytics.MaxSize ji na nezápornou hodnotu. Hodnota VSTS.Analytics.MaxSize představuje maximální počet záznamů, které můžete přijmout. Pokud ji nastavíte na nulu, použije se výchozí hodnota 200 K.

Následující dotaz například vrátí pracovní položky, pokud je datová sada menší nebo rovna 1000 záznamům.

GET https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems HTTP/1.1
User-Agent: {application}
Prefer: VSTS.Analytics.MaxSize=1000
OData-MaxVersion: 4.0
Accept: application/json;odata.metadata=minimal
Host: analytics.dev.azure.com/{OrganizationName}

Pokud datová sada překročí limit 1 000 záznamů, dotaz okamžitě selže s následující chybou.

Výsledek dotazu obsahuje 1 296 řádků a překračuje maximální povolenou velikost 1 000. Snižte počet záznamů použitím dalších filtrů.

Informace o nastavení maximální velikosti stránky naleznete v ODataPreferenceHeader.MaxPageSize vlastnost.

Pokyny pro styl dotazů

✔️ Do use $count virtual property in the aggregation methods

Některé entity zpřístupňují Count vlastnost. Některé scénáře vytváření sestav usnadňují export dat do jiného úložiště. Tyto sloupce byste ale neměli používat v agregacích v dotazech OData. $count Místo toho použijte virtuální vlastnost.

Například následující dotaz vrátí celkový počet pracovních položek.

https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
  $apply=aggregate($count as Count)

❌ Vyhněte se použití $count virtuální vlastnosti v segmentu adresy URL

I když standard OData umožňuje použít $count virtuální vlastnost pro sady entit (například _odata/v1.0/WorkItems/$count), ne všichni klienti mohou interpretovat odpověď správně. Proto doporučujeme místo toho použít agregace.

Například následující dotaz vrátí celkový počet pracovních položek.

https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
  $apply=aggregate($count as Count)

✔️ ZVAŽTE použití aliasů parametrů k oddělení nestálých částí dotazu.

Aliasy parametrů poskytují elegantní řešení pro extrakci nestálých částí, jako jsou hodnoty parametrů z hlavního textu dotazu. Můžete je použít ve výrazech, které vyhodnocují:

  • Primitivní hodnota
  • Složitá hodnota
  • Kolekce primitivních nebo složitých hodnot.

Další informace najdete v tématu OData verze 4.0. Část 2: Konvence adres URL - 5.1.1.13 Aliasy parametrů. Parametry jsou užitečné, když se text dotazu používá jako šablona, která se dá vytvořit instancí s hodnotami zadanými uživatelem.

Například následující dotaz používá @createdDateSK parametr k oddělení hodnoty od výrazu filtru.

https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
  $filter=CreatedDateSK ge @createdDateSK
  &$select=WorkItemId, Title, State
  &@createdDateSK=20200101

❌ Vyhněte se kombinování $apply a $filter klauzulí v jednom dotazu

Pokud chcete přidat filter do dotazu, máte dvě možnosti. Můžete to udělat buď pomocí $filter klauzule, nebo kombinace $apply=filter() . Každá z těchto možností funguje skvěle samostatně, ale jejich kombinování může vést k neočekávaným výsledkům.

Navzdory očekávání, které může mít, OData jasně definuje pořadí vyhodnocení. Klauzule má také prioritu $apply nad $filter. Z tohoto důvodu byste měli zvolit jednu nebo druhou, ale vyhnout se těmto dvěma možnostem filtru v jednom dotazu. Je důležité, pokud se dotazy generují automaticky.

Například následující dotaz nejprve filtruje pracovní položky podle StoryPoint gt 5, agreguje výsledky podle cesty a nakonec filtruje výsledek podle StoryPoints gt 2. V tomto pořadí vyhodnocení dotaz vždy vrátí prázdnou sadu.

https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
  $filter=StoryPoints gt 2
  $apply=
    filter(StoryPoints gt 5)/
    groupby(
      (Area/AreaPath),
      aggregate(StoryPoints with sum as StoryPoints)
    )

✔️ ZVAŽTE strukturování dotazu tak, aby odpovídalo pořadí vyhodnocení OData.

Protože kombinování $apply a filter klauzule v jednom dotazu můžou vést k potenciálním nejasnostem, doporučujeme strukturovat klauzule dotazu tak, aby odpovídaly pořadí vyhodnocení.

  1. $apply
  2. $filter
  3. $orderby
  4. $expand
  5. $select
  6. $skip
  7. $top

✔️ ZVAŽTE kontrolu možností OData popsaných v poznámkách metadat.

Pokud si nejste jistí, které možnosti OData Analytics podporují, můžete vyhledat poznámky v metadatech. Technický výbor OASIS Open Data Protocol (OData) v úložišti TC GitHub udržuje seznam dostupných poznámek.

Seznam podporovaných funkcí filtru je například k dispozici v Org.OData.Capabilities.V1.FilterFunctions poznámce v kontejneru entit.

<Annotation Term="Org.OData.Capabilities.V1.FilterFunctions">
  <Collection>
  <String>contains</String>
  <String>endswith</String>
  [...]
  </Collection>
</Annotation>

Další užitečnou poznámkou je Org.OData.Capabilities.V1.ExpandRestrictions, která vysvětluje, které navigační vlastnosti nemůžete v klauzuli $expand použít. Například následující poznámka vysvětluje, že Revisions v WorkItems sadě entit nelze rozbalit.

<EntitySet Name="WorkItems" EntityType="Microsoft.VisualStudio.Services.Analytics.Model.WorkItem">
  [...]
  <Annotation Term="Org.OData.Capabilities.V1.ExpandRestrictions">
    <Record>
      <PropertyValue Property="Expandable" Bool="true"/>
      <PropertyValue Property="NonExpandableProperties">
        <Collection>
          <NavigationPropertyPath>Revisions</NavigationPropertyPath>
        </Collection>
      </PropertyValue>
    </Record>
  </Annotation>
</EntitySet>