Wytyczne dotyczące zapytań analizy OData dla usługi Azure DevOps
Azure DevOps Services | Azure DevOps Server 2022 — Azure DevOps Server 2019
Deweloperzy rozszerzeń mogą skorzystać, postępując zgodnie z wytycznymi podanymi w tym artykule dotyczącymi projektowania wydajnych zapytań OData względem analizy dla usługi Azure DevOps. Przestrzeganie tych wytycznych pomaga zagwarantować, że zapytania mają dobrą wydajność w czasie wykonywania i zużyciu zasobów. Zapytania, które nie są zgodne z tymi wytycznymi, mogą spowodować niską wydajność z długim czasem oczekiwania raportu, zapytaniami przekraczającymi dozwolone użycie zasobów lub blokadami usług.
Uwaga
Usługa Analytics jest automatycznie włączona i obsługiwana w środowisku produkcyjnym dla wszystkich usług Azure DevOps Services.
Integracja usługi Power BI i dostęp do źródła danych OData usługi Analytics są ogólnie dostępne. Zachęcamy do korzystania z niego i przekazywania opinii.
Dostępne dane są zależne od wersji. Najnowsza obsługiwana wersja to v2.0
, a najnowsza wersja zapoznawcza to v4.0-preview
. Aby uzyskać więcej informacji, zobacz Wersjonowanie interfejsu API OData.
Uwaga
Usługa Analytics jest automatycznie instalowana i obsługiwana w środowisku produkcyjnym dla wszystkich nowych kolekcji projektów dla usługi Azure DevOps Server 2020 i nowszych wersji. Integracja usługi Power BI i dostęp do źródła danych OData usługi Analytics są ogólnie dostępne. Zachęcamy do korzystania z niego i przekazywania opinii. W przypadku uaktualnienia z usługi Azure DevOps Server 2019 możesz zainstalować usługę Analytics podczas uaktualniania.
Dostępne dane są zależne od wersji. Najnowsza obsługiwana wersja to v2.0
, a najnowsza wersja zapoznawcza to v4.0-preview
. Aby uzyskać więcej informacji, zobacz wersjonowanie interfejsu API OData.
Te wytyczne są naszymi zaleceniami poprzedzonymi terminami DO, ROZWAŻ, UNIKAJ i NIE. Restrykcyjne reguły wymuszane przez usługę Analytics zawierają prefiks [BLOCKED]. Należy zrozumieć kompromisy między różnymi rozwiązaniami. W pewnych okolicznościach mogą istnieć wymagania dotyczące danych, które wymuszają naruszenie co najmniej jednej z wytycznych. Takie przypadki powinny być rzadkie. Zalecamy, aby mieć jasny i przekonujący powód takich decyzji.
Napiwek
Przykłady przedstawione w tym dokumencie są oparte na adresie URL usługi Azure DevOps Services. Użyj zamienników dla wersji miejscowych.
https://{servername}:{port}/tfs/{OrganizationName}/{ProjectName}/_odata/{version}/
Komunikaty o błędach i ostrzeżenia
✔️ Przeanalizuj ostrzeżenia odpowiedzi OData
Każde wykonywane zapytanie jest sprawdzane względem zestawu wstępnie zdefiniowanych reguł. W przypadku naruszeń odpowiedź OData jest zwracana po @vsts.warnings
. Przejrzyj te ostrzeżenia, ponieważ udostępniają bieżące i kontekstowe informacje na temat ulepszania zapytania.
{
"@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."
],
...
}
✔️ Przejrzyj komunikaty o błędach OData
Zapytania naruszające regułę błędu OData powoduje niepowodzenie odpowiedzi z kodem stanu 400 (nieprawidłowe żądanie). Komunikaty skojarzone nie pojawiają się we właściwości @vsts.warnings
. Zamiast tego generują komunikat o błędzie w polu właściwości w odpowiedzi 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."
}
}
Ograniczenia
Czy
- ✔️ Ogranicz zapytanie do projektów, do których masz dostęp
-
✔️ Określ filtr projektu wewnątrz klauzuli
$expand
, jeśli twoje rozszerzenie może zawierać dane w innych, potencjalnie niedostępnych projektach - ✔️ Zaczekaj lub zatrzymaj operację, jeśli zapytanie przekroczy limity użycia
- ✔️ Zaczekaj lub zatrzymaj operację, jeśli zapytanie zakończy się niepowodzeniem z przekroczeniem limitu czasu
- ✔️ Dołącz
DateSK
lubDateValue
kolumnę w klauzuligroupby
podczas agregowania tabel migawek - ✔️ Wyraźne adresowanie bytów za pomocą klauzul filtra
-
✔️ Używaj
WorkItemRevisions
zestawu encji, aby załadować wszystkie poprawki dla danego elementu roboczego - ✔️ Użyj punktu końcowego wsadowego dla długich zapytań
- ✔️ Należy określać strefę czasową podczas filtrowania kolumn z datami
Rozważ następujące kwestie
Zablokowano
- ❌ [ZABLOKOWANE] Nie używaj jednostek migawek do niczego innego niż agregacje
- ❌ [ZABLOKOWANE] Nie używaj kluczy jednostek w ścieżkach zasobów na potrzeby adresowania jednostek
-
❌ [ZABLOKOWANE] Nie rozszerzaj
Revisions
naWorkItem
podmiocie - ❌ [ZABLOKOWANE] Nie grupuj na odrębnych kolumnach
-
❌ [ZABLOKOWANE] Nie używaj
countdistinct
agregacji - ❌ [ZABLOKOWANE] Nie używaj punktu końcowego wsadowego do wysyłania wielu zapytań
- ❌ [ZABLOKOWANE] Nie używaj zapytań, które powodują więcej niż 800 kolumn
Uniknięcie
- ❌ UNIKAJ agregacji, które mogą powodować przepełnienie arytmetyczne
- ❌ UNIKAJ tworzenia długich zapytań
✔️ Ogranicz zapytanie do projektów, do których masz dostęp
Jeśli zapytanie dotyczy danych z projektu, do którego nie masz dostępu, zapytanie zwraca komunikat "Odmowa dostępu do projektu". Aby upewnić się, że masz dostęp, sprawdź, czy uprawnienie Wyświetl analizę jest ustawione na Zezwalaj dla wszystkich projektów, o które pytasz. Aby uzyskać więcej informacji, zobacz Uprawnienia wymagane do uzyskania dostępu do analizy.
Jeśli nie masz dostępu do projektu, zostanie wyświetlony następujący komunikat:
Wyniki zapytania obejmują dane w jednym lub kilku projektach, dla których nie masz dostępu. Dodaj co najmniej jeden filtr projektów, aby określić projekty, do których masz dostęp w jednostce "WorkItems". Jeśli używasz $expand lub właściwości nawigacji, filtr projektu jest wymagany dla tych jednostek.
Aby obejść ten problem, możesz jawnie dodać filtr projektu lub użyć punktu końcowego specyficznego dla projektu, co wyjaśniono w dalszej części artykułu.
Na przykład następujące zapytanie pobiera elementy robocze, które należą do projektów o nazwach {projectSK1}
i {projectSK2}
.
https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
$filter=ProjectSK eq {projectSK1} or ProjectSK eq {projectSK2}
&$select=WorkItemId, Title
✔️ Należy określić filtr projektu wewnątrz klauzuli $expand
, w przypadku gdy rozszerzenie może zawierać dane w innych, potencjalnie niedostępnych projektach
Po rozwinięciu właściwości nawigacji istnieje prawdopodobieństwo, że odwołujesz się do danych z innych, niedostępnych projektów. Jeśli odwołujesz się do niedostępnych danych, zostanie wyświetlony ten sam komunikat o błędzie wymieniony wcześniej: "Wyniki zapytania zawierają dane w jednym lub kilku projektach...". Podobnie możesz rozwiązać ten problem, dodając jawne filtry projektu w celu kontrolowania rozszerzonych danych.
Można to zrobić w klauzuli regularnej $filter
dla prostych właściwości nawigacji. Na przykład następujące zapytanie jawnie prosi o WorkItemLinks
, gdzie zarówno link, jak i jego cel istnieją w tym samym projekcie.
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)
Zamiast tego możesz przenieść filtr do opcji rozwinięcia $filter
w klauzuli $expand
. Jednak zmienia semantykę kwerendy. Na przykład następujące zapytanie pobiera wszystkie linki z danego projektu i warunkowo rozszerza obiekt docelowy tylko wtedy, gdy istnieje w tym samym projekcie. Mimo że jest prawidłowe, takie podejście może spowodować zamieszanie, ponieważ może być trudno określić, czy właściwość nie jest rozwinięta z powodu null
czy dlatego, że została odfiltrowana. Używaj tego rozwiązania tylko wtedy, gdy naprawdę potrzebujesz takiego konkretnego zachowania.
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)
Opcja rozszerzenia $filter
jest przydatna w przypadku używania właściwości rozszerzenia kolekcji, takiej jak Children
w WorkItems
zbiorze encji. Na przykład następujące zapytanie zwraca wszystkie elementy robocze z danego projektu wraz ze wszystkimi ich elementami podrzędnymi, które również należą do tego samego 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)
Określ filtr, jeśli rozwiń jedną z następujących właściwości:
-
WorkItems
zestaw jednostek:Parent
,Children
-
WorkItemLinks
zestaw jednostek:TargetWorkItem
.
✔️ ROZWAŻ wykonywanie zapytań przy użyciu punktu końcowego z zakresem projektu
Jeśli interesują Cię dane z jednego projektu, zalecamy użycie punktu końcowego OData o zakresie projektu (/{ProjectName}/_odata/v1.0
). Pozwala uniknąć problemów opisanych w poprzednich dwóch sekcjach i niejawnie filtruje dane do jednego projektu, przywoływany zestaw jednostek i wszystkie rozwinięte właściwości nawigacji.
Z tym uproszczeniem zapytania z poprzedniej sekcji mogą zostać przepisane do następującego formularza. Nie tylko filtr w klauzuli expand zniknął, ale także nie ma potrzeby filtru w głównym zbiorze jednostek.
https://analytics.dev.azure.com/{OrganizationName}/{ProjectName}/_odata/{version}//WorkItemLinks?
&$select=LinkTypeReferenceName, SourceWorkItemId, TargetWorkItemId
&$expand=TargetWorkItem($select=WorkItemId, Title)
Zapytanie dotyczące elementów roboczych podrzędnych jest również znacznie krótsze i prostsze.
https://analytics.dev.azure.com/{OrganizationName}/{ProjectName}/_odata/{version}//WorkItems?
&$select=WorkItemId, Title
&$expand=Children($select=WorkItemId, Title)
To rozwiązanie można zastosować tylko wtedy, gdy fokus dotyczy danych z pojedynczego projektu. W przypadku raportowania między projektami należy użyć strategii filtrowania opisanych w poprzednich sekcjach.
✔️ Zaczekaj lub zatrzymaj operację, jeśli zapytanie przekroczy limity użycia
Jeśli wykonujesz wiele zapytań lub zapytania wymagają wielu zasobów do uruchomienia, możesz przekroczyć limity usług i zostać tymczasowo zablokowany. Jeśli przekroczysz limity usługi, zatrzymaj operację, ponieważ istnieje prawdopodobieństwo, że następne zapytanie, które wysyłasz, spotka się z niepowodzeniem i otrzymasz ten sam komunikat o błędzie.
Żądanie zostało zablokowane z powodu przekroczenia użycia zasobu "{resource}" w przestrzeni nazw "{namespace}".
Aby uzyskać więcej informacji na temat ograniczania szybkości, zobacz Limity szybkości. Aby dowiedzieć się, jak projektować wydajne zapytania OData, zapoznaj się z wytycznymi dotyczącymi wydajności w dalszej części tego artykułu.
✔️ Zaczekaj lub zatrzymaj operację, jeśli zapytanie zakończy się niepowodzeniem z powodu przekroczenia limitu czasu
Podobnie jak w przypadku przekroczenia limitów użycia, należy poczekać lub zatrzymać operację w przypadku przekroczenia limitu czasu zapytania. Może to sygnalizować przejściowy problem, więc możesz ponowić próbę raz, aby sprawdzić, czy problem zostanie rozwiązany. Jednak trwałe przekroczenia limitu czasu wskazują, że zapytanie jest prawdopodobnie zbyt kosztowne do uruchomienia. Dalsze ponawianie prób powoduje przekroczenie limitów użycia i zablokowanie.
TF400733: Żądanie zostało anulowane: Żądanie przekroczyło limit czasu żądania, spróbuj ponownie.
Limity czasu wskazują, że zapytanie wymaga optymalizacji. Aby dowiedzieć się, jak projektować wydajne zapytania OData, zobacz Wytyczne dotyczące wydajności w dalszej części tego artykułu.
❌ [ZABLOKOWANE] Nie używaj jednostek migawkowych do niczego innego niż agregacje
Zestawy jednostek migawek z sufiksem Snapshot
są specjalne, ponieważ są modelowane jako codzienne migawki. Można ich użyć, aby uzyskać stan podmiotów takim, jaki był na koniec każdego dnia w przeszłości. Jeśli na przykład wykonałeś zapytanie dotyczące WorkItemSnapshot
i przefiltrowałeś do pojedynczego WorkItemId
, otrzymasz jeden rekord dla każdego dnia od dnia utworzenia elementu roboczego. Ładowanie bezpośrednio wszystkich tych danych byłoby kosztowne i najprawdopodobniej przekroczy limity użycia i zostanie zablokowane. Jednak agregacje tych jednostek są dozwolone i zalecane. W rzeczywistości zestawy jednostek migawki zostały zaprojektowane z myślą o scenariuszach agregacji.
Na przykład następujące zapytanie pobiera liczbę elementów roboczych według daty, aby zaobserwować, jak to wzrosło w styczniu 2020 r.
https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItemSnapshot?
$apply=
filter(DateSK ge 20200101 and DateSK le 20200131)/
groupby((DateSK), aggregate($count as Count))
Aby uzyskać więcej informacji na temat agregacji, zobacz Agregowanie danych.
✔️ Dołącz DateSK
lub DateValue
kolumnę w klauzuli groupby
podczas agregowania nad tabelami migawkowymi
Ponieważ wszystkie jednostki migawek są modelowane jako codzienne tabele migawek, zawsze należy uwzględnić jedną z właściwości dnia (DateSK
lub DateValue
) w klauzuli grupowania. W przeciwnym razie wynik może pojawić się niepoprawnie zawyżony.
Jeśli na przykład pogrupowano WorkItemSnapshot
tylko według właściwości AssignedTo
i zagregowano ją, używając liczby, każda liczba elementów pracy przypisanych ludziom byłaby pomnożona przez liczbę dni, w których dane przypisanie było aktywne. Chociaż może wystąpić sytuacja, w której jest to pożądany wynik, takie przypadki są rzadkie.
❌ [ZABLOKOWANE] Nie używaj kluczy jednostek w ścieżkach zasobów na potrzeby adresowania jednostek
Składnia OData umożliwia uzyskiwanie dostępu do określonej jednostki przez uwzględnienie kluczy bezpośrednio w segmentach adresów URL. Aby uzyskać więcej informacji, zobacz OData w wersji 4.0. Część 2. Konwencje adresów URL — 4.3 adresowanie jednostek. Mimo że usługa OData zezwala na takie adresowanie, usługa Analytics blokuje je. Dołączenie do zapytania powoduje następujący błąd.
Kwerenda określona w identyfikatorze URI jest nieprawidłowa. Analiza nie obsługuje nawigacji po kluczach lub właściwościach takich jak WorkItems(Id) ani WorkItem(Id)/AssignedTo. Jeśli wystąpi ten błąd w usłudze Power BI, napisz ponownie zapytanie, aby uniknąć nieprawidłowego składania, które powoduje problem N+1.
Jak wskazują komunikaty o błędach, pewne narzędzia klienckie mogą nadużywać bezpośredniego adresowania jednostek. Zamiast ładować wszystkie dane w jednym żądaniu, klienci mogą zdecydować się na niezależne wykonywanie zapytań dotyczących każdej jednostki. Ta praktyka jest zniechęcana, ponieważ może to spowodować dużą liczbę żądań. Zamiast tego zalecamy używanie jawnego adresowania jednostek zgodnie z wyjaśnieniem w poniższej sekcji.
✔️ Jawnie adresuj jednostki za pomocą klauzul filtru
Jeśli chcesz pobrać dane dla pojedynczej jednostki, należy użyć tego samego podejścia co w przypadku kolekcji jednostek i jawnie zdefiniować filtry w klauzuli $filter
.
Na przykład następujące zapytanie pobiera pojedynczy element pracy według jego identyfikatora.
https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
$filter=WorkItemId eq {id}
&$select=WorkItemId, Title
Jeśli nie masz pewności, które właściwości należy uwzględnić w takim filtrze, możesz wyszukać je w metadanych. Zobacz Jak konstruować zapytania OData dla analityki oraz składniki adresu URL do zapytań o metadane. Właściwości znajdują się w Key
elemencie EntityType
. Na przykład WorkItemId
i Revision
są kluczowymi kolumnami dla jednostki WorkItemRevision
.
<EntityType Name="WorkItemRevision">
<Key>
<PropertyRef Name="WorkItemId"/>
<PropertyRef Name="Revision"/>
</Key>
[...]
</EntityType>
❌ [ZABLOKOWANE] Nie rozszerzaj Revisions
na WorkItem
jednostce
Model danych analizy nie zezwala na pewne typy rozszerzeń. Jedną z nich, co może być zaskakujące dla niektórych, jest Revisions
właściwość kolekcji w jednostce WorkItem
. Jeśli spróbujesz rozwinąć tę właściwość, zostanie wyświetlony następujący komunikat o błędzie.
Zapytanie określone w identyfikatorze URI jest nieprawidłowe. Nie można użyć właściwości "Revisions" w opcji zapytania $expand.
To ograniczenie zostało wprowadzone, aby zachęcić wszystkich do korzystania z zalecanego rozwiązania, polegającego na pobieraniu poprawek z WorkItemRevisions
zgodnie z wyjaśnieniem w poniższej sekcji.
✔️ Należy użyć WorkItemRevisions
zestawu encji, aby załadować wszystkie poprawki dla danego elementu roboczego
Użyj WorkItemRevisions
za każdym razem, gdy chcesz pobrać pełną historię elementu roboczego lub kolekcji elementów roboczych.
Na przykład następujące zapytanie zwraca wszystkie poprawki elementu roboczego z identyfikatorem {id}
.
https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItemRevisions?
$filter=WorkItemId eq {id}
&$select=WorkItemId, Title
Jeśli zależy Ci na pełnej historii wszystkich elementów roboczych spełniających określone kryteria, należy wyrazić ją przy użyciu filtru we WorkItem
właściwości nawigacji. Na przykład następujące zapytanie pobiera wszystkie wersje wszystkich aktualnie aktywnych elementów roboczych.
https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItemRevisions?
$filter=WorkItem/State eq 'Active'
&$select=WorkItemId, Title
❌ [ZABLOKOWANE] Nie grupuj na odrębnych kolumnach
Aby zmniejszyć liczbę rekordów, należy użyć operacji grupowania. Użycie odrębnych kolumn w klauzuli groupby
wskazuje problem, a zapytanie natychmiast kończy się niepowodzeniem. Jeśli przypadkowo wystąpi taka sytuacja, zostanie wyświetlony następujący komunikat o błędzie.
Jedna lub więcej kolumn określonych w klauzuli 'groupby' tego zapytania nie jest zalecana.
Aby rozwiązać ten problem, usuń odrębną kolumnę z klauzuli groupby
.
❌ [ZABLOKOWANE] Nie używaj countdistinct
agregacji
Analiza nie obsługuje funkcji countdistinct
, mimo że OData to robi. Chociaż planujemy dodać obsługę w przyszłości, obecnie nie jest ona dostępna. Zapytanie zawierające tę funkcję zwraca następujący komunikat o błędzie.
Zapytania, które stosują zliczanie unikalnych wartości wraz z agregacją, nie są obsługiwane.
❌ UNIKAJ agregacji, które mogą prowadzić do przepełnienia arytmetycznego
W rzadkich przypadkach zapytanie agregacji może napotkać problemy z przepełnieniem arytmetycznym. Na przykład może się zdarzyć, gdy sumujesz niektóre właściwości liczbowe, które nie są przeznaczone do sumowania, na przykład StackRank
w jednostkach elementu roboczego.
Ponieważ rozszerzenie OData dla standardu agregacji danych nie zapewnia sposobu rzutowania właściwości na inny typ, jedynym sposobem rozwiązania tego problemu jest usunięcie problematycznej właściwości z agregacji.
✔️ Użyj punktu końcowego wsadowego dla długich zapytań
Mogą wystąpić problemy z długimi zapytaniami. Szczególnie problemy mogą wystąpić, gdy:
- Wykonasz zapytanie dotyczące projektu z wieloma polami niestandardowymi.
- Zapytanie jest konstruowane programowo.
Bieżący limit wysyłanych HTTP GET
zapytań OData wynosi 3000 znaków. Jeśli go przekroczysz, otrzymasz odpowiedź "404 Nie znaleziono".
HTTP/1.1 404 Not Found
Content-Length: 0
Aby rozwiązać ten problem, użyj punktu końcowego wsadowego OData zgodnie ze specyfikacją, OData wersja 4.0. Część 1: Protokół — 11.7 Żądania wsadowe. Funkcja usługi Batch została zaprojektowana głównie w celu grupowania wielu operacji w jednym HTTP
ładunku żądania, ale można jej również użyć jako obejścia ograniczenia długości zapytania. Wysyłając HTTP POST
żądanie, możesz przekazać zapytanie o dowolną długość, a usługa je poprawnie interpretuje.
❌ [ZABLOKOWANE] Nie używaj punktu końcowego wsadowego do wysyłania wielu zapytań
Ograniczamy użycie punktu końcowego wsadowego, aby uniemożliwić przetwarzanie wielu żądań jednocześnie. Pojedyncze żądanie nadal może mieć tylko jedno zapytanie. Jeśli spróbujesz wysłać partię kilku zapytań, operacja zakończy się niepowodzeniem z następującym komunikatem o błędzie. Jedynym rozwiązaniem jest podzielenie zapytań na wiele żądań.
Analityka nie obsługuje przetwarzania wielu operacji zawartych w bieżącym komunikacie wsadowym. Analiza używa usługi OData batch w celu obsługi żądań POST, ale wymaga ograniczenia operacji do pojedynczego żądania.
❌ [ZABLOKOWANE] Nie używaj zapytań, które powodują więcej niż 800 kolumn
Ograniczamy zapytania, które powodują więcej niż 800 kolumn. Jeśli nie jesteś wystarczająco selektywny, w których kolumny zwraca zapytanie, może zostać wyświetlony następujący komunikat o błędzie.
VS403670: określone zapytanie zwraca kolumny "N", które są wyższe niż dozwolony limit 800 kolumn. Aby ograniczyć liczbę kolumn, używaj jawnych opcji $select, w tym również wewnątrz $expand.
Dodaj klauzulę $select do zapytania oraz $expand do operacji w zapytaniu, aby uniknąć przekroczenia tego limitu.
❌ UNIKAJ tworzenia długich zapytań
Zalecamy ocenę podejścia za każdym razem, gdy utworzysz długie zapytanie. Istnieje wiele scenariuszy, które wymagają długiego zapytania (na przykład złożonych filtrów lub długiej listy właściwości), ale zazwyczaj stanowią one wczesny wskaźnik nieoptymalnego projektu.
Jeśli zapytanie zawiera wiele kluczy jednostki w zapytaniu (na przykład WorkItemId eq {id 1} or WorkItemId eq {id 2} or ...
), prawdopodobnie możesz go ponownie napisać. Zamiast przekazywać identyfikatory, spróbuj zdefiniować inne kryteria, które wybierają ten sam zestaw jednostek. Czasami może być konieczne zmodyfikowanie procesu (na przykład dodanie nowego pola lub tagu), ale zazwyczaj warto. Zapytania korzystające z bardziej abstrakcyjnych filtrów są łatwiejsze do utrzymania i mają większy potencjał do lepszego działania.
Inny scenariusz, który ma tendencję do generowania długich zapytań, występuje w przypadku uwzględnienia wielu pojedynczych dat (na przykład DateSK eq {dateSK 1} or DateSK eq {dateSK 2} or ...
). Poszukaj innego wzorca, którego można użyć do utworzenia bardziej abstrakcyjnego filtru. Na przykład następujące zapytanie zwraca wszystkie elementy robocze, które zostały utworzone w poniedziałek.
https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
$filter=CreatedOn/DayOfWeek eq 2
&$select=WorkItemId, Title, State
✔️ CZY określać strefę czasową podczas filtrowania kolumn dat
Strefa czasowa (Edm.DateTimeOffset
) uwidacznia wszystkie informacje o dacie i godzinie z przesunięciem zgodnym z ustawieniami strefy czasowej organizacji. Te dane są dokładne i proste do zinterpretowania w tym samym czasie. Kolejną nieoczywistą konsekwencją jest to, że wszystkie filtry muszą również przekazać informacje o strefie czasowej. Jeśli pominiesz go, zostanie wyświetlony następujący komunikat o błędzie.
Kwerenda określona w identyfikatorze URI jest nieprawidłowa. Nie określono przesunięcia daty/godziny. Użyj jednego z tych formatów RRRR-MM-ddZ, aby określić wszystko od godziny północnej lub RRRR-MM-ddThh:mm-hh:mm (standardowa reprezentacja dat i godzin ISO 8601) w celu określenia różnicy czasowej.
Aby rozwiązać ten problem, dodaj informacje o strefie czasowej. Na przykład przy założeniu, że organizacja jest skonfigurowana do wyświetlania danych w strefie czasowej pacyficznej (STANY ZJEDNOCZONE i Kanada) (UTC-08:00), następujące zapytanie pobiera wszystkie elementy robocze utworzone od początku 2020 roku.
https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
$filter=CreatedDate ge 2020-01-01T00:00:00-08:00
&$select=WorkItemId, Title, State
To samo rozwiązanie działa w przypadku stref czasowych z dodatnimi przesunięciami, jednak znak plus (+
) ma specjalne znaczenie w identyfikatorze URI i musisz go poprawnie obsłużyć. Jeśli określisz 2020-01-01T00:00:00+08:00
(z znakiem +
) jako punkt początkowy, zostanie wyświetlony następujący błąd.
Zapytanie określone w identyfikatorze URI jest nieprawidłowe. Błąd składniowy na pozycji 31 w "CreatedDate ge 2020-01-01T0000 08:00".
Aby rozwiązać ten problem, zastąp +
znak jego zakodowaną wersją , %2B
. Na przykład, przy założeniu, że organizacja jest skonfigurowana do wyświetlania danych w strefie czasowej "(UTC+08:00) Pekin, Chongqing, Hong Kong, Urumqi", następujące zapytanie zwraca wszystkie elementy robocze utworzone od początku 2020 roku.
https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
$filter=CreatedDate ge 2020-01-01T00:00:00%2B08:00
&$select=WorkItemId, Title, State
Alternatywną metodą jest użycie właściwości klucza zastępczego daty, ponieważ nie przechowują informacji o strefie czasowej. Na przykład następujące zapytanie zwraca wszystkie elementy robocze utworzone od początku 2020 r., niezależnie od ustawień organizacji.
https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
$filter=CreatedDateSK ge 20200101
&$select=WorkItemId, Title, State
Wytyczne dotyczące wydajności
Czy
- ✔️ DO measure the effect of wdrożenia wytycznych wydajności
- ✔️ Używaj rozszerzeń agregacji
-
✔️ Określ kolumny w tej klauzuli
$select
-
✔️ Określ kolumny w opcji rozwijania
$select
wewnątrz klauzuli$expand
-
✔️ Zdefiniuj filtr na
RevisedDateSK
, gdy tworzysz zapytania o historyczne dane elementów roboczych (WorkItemRevisions
lubWorkItemSnapshot
zestawy encji) - ✔️ Używaj cotygodniowych lub miesięcznych migawek na zapytania dotyczące trendów, które obejmują długi okres czasu
- ✔️ Użyj właściwości kolekcji w elementach roboczych podczas filtrowania według tagów
-
✔️
TagNames
Użyj właściwości DO, jeśli chcesz wyświetlić wszystkie tagi w elemencie roboczym jako tekst - ✔️ Używaj stronicowania opartego na serwerze
-
✔️
$top
Użyj opcji kwerendy, aby ograniczyć liczbę rekordów
Czego nie robić
-
❌ Nie używaj
tolower
i funkcjitoupper
do porównywania bez uwzględniania wielkości liter -
❌ Nie używaj nieograniczonego rozszerzenia z
$levels=max
-
❌ Nie używaj
$top
opcji zapytania i$skip
do implementowania stronicowania opartego na kliencie
Rozważ następujące kwestie
- ✔️ ROZWAŻ pisanie zapytań tak, aby zwracały niewielką liczbę rekordów
- ✔️ ROZWAŻ ograniczenie liczby wybranych właściwości do minimum
-
✔️ ZASTANÓW SIĘ NAD filtrowaniem właściwości klucza zastępczego daty z użyciem sufiksu (
DateSK
) - ✔️ ROZWAŻ filtrowanie kolumn kluczy zastępczych
-
✔️ ROZWAŻ przekazanie
vsts.analytics.maxsize
preferencji w nagłówku
Uniknięcie
✔️ DO measure the effect of implement a performance wytyczne
Podobnie jak w przypadku żadnych zaleceń dotyczących wydajności, nie należy ich ślepo implementować. Zamiast tego należy zawsze przechwytywać punkt odniesienia i mierzyć efekt wprowadzonych zmian. Wszystkie wytyczne zostały utworzone na podstawie interakcji z klientami analizy, którzy mieli określone wymagania i wyzwania. Te zalecenia zostały uznane za ogólne i potencjalnie przydatne dla każdego, kto projektuje podobne zapytania. Jednak w rzadkich przypadkach przestrzeganie wytycznych nie może mieć wpływu ani nawet negatywnego wpływu na wydajność. Musisz zmierzyć różnicę, aby ją zauważyć. Jeśli tak się stanie, przekaż opinię w portalu Społeczności deweloperów.
Istnieje wiele opcji mierzenia wydajności. Najprostszym z nich jest uruchomienie dwóch wersji tego samego zapytania bezpośrednio w przeglądarce. Obserwuj czas, jaki zajmuje to w narzędziach deweloperskich. Na przykład można użyć panelu sieci w narzędziu Microsoft Edge F12 Developer Tools. Inną opcją jest przechwycenie tych informacji przy użyciu narzędzia Fiddler Web Debugger Tool.
Niezależnie od podejścia, uruchom oba zapytania wiele razy. Na przykład uruchom zapytania 30 razy, aby mieć wystarczająco duży zestaw próbek. Następnie ustalizuj charakterystykę wydajności. Analiza jest zgodna z architekturą wielodostępną. Dlatego inne operacje występujące w tym samym czasie mogą mieć wpływ na czas trwania zapytań.
✔️ Używaj rozszerzeń agregacji
Zdecydowanie najlepszą rzeczą, jaką można zrobić, aby zwiększyć wydajność zapytań, jest użycie rozszerzenia agregacji — rozszerzenie OData dla agregacji danych. Za pomocą rozszerzenia agregacji poproś usługę o przeprowadzenie podsumowania danych po stronie serwera i zwrócenie odpowiedzi, która będzie mniejsza niż ta, którą można uzyskać, stosując tę samą funkcję po stronie klienta. Na koniec analiza jest zoptymalizowana pod kątem tego typu zapytań, więc korzystaj z niej.
Aby uzyskać więcej informacji, zobacz Agregowanie danych.
✔️ DO określ kolumny w klauzuli $select
Określ kolumny, o których mowa w klauzuli $select
. Analiza jest oparta na technologii Indeks magazynu kolumnowego. Oznacza to, że dane są przechowywane i przetwarzanie zapytań jest oparte na kolumnach. Zmniejszając zestaw właściwości w klauzuli $select
, możesz zmniejszyć liczbę kolumn, które muszą zostać zeskanowane, co poprawia ogólną wydajność zapytania.
Na przykład następujące zapytanie określa kolumny elementów roboczych.
https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
$select=WorkItemId, Title, State
Uwaga
Usługa Azure DevOps obsługuje dostosowywanie procesów. Niektórzy administratorzy używają tej funkcji i tworzą setki pól niestandardowych. Jeśli pominiesz klauzulę $select
, zapytanie zwróci wszystkie pola, w tym pola niestandardowe.
✔️ Określić kolumny w opcji rozwinięcia $select
wewnątrz klauzuli $expand
Podobnie jak w przypadku wytycznych dotyczących klauzuli $select
, określ właściwości w opcji rozwijania $select
wewnątrz klauzuli $expand
. Łatwo zapomnieć, ale jeśli pominięto ją, odpowiedź zawiera wszystkie właściwości obiektu rozwiniętego.
Na przykład następujące zapytanie określa kolumny zarówno dla elementu roboczego, jak i jego elementu nadrzędnego.
https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
$select=WorkItemId, Title, State
&$expand=Parent($select=WorkItemId, Title, State)
✔️ Zdefiniuj filtr na RevisedDateSK
podczas wykonywania zapytań o historyczne dane elementów roboczych (WorkItemRevisions
lub WorkItemSnapshot
zestawów jednostek)
Podczas wykonywania zapytań dotyczących danych historycznych jest prawdopodobne, że interesujesz się najnowszym okresem (na przykład 30 dni, 90 dni). Ze względu na sposób implementowania jednostek elementów roboczych istnieje wygodny sposób pisania takich zapytań w celu uzyskania wysokiej wydajności. Za każdym razem, gdy aktualizujesz element roboczy, tworzy nową poprawkę i rejestruje tę akcję w System.RevisedDate
polu, co sprawia, że idealnie nadaje się do filtrów historii.
W sekcji Analytics zmieniona data jest wyświetlana we właściwościach RevisedDate
(Edm.DateTimeOffset
) i RevisedDateSK
(Edm.Int32
). Aby uzyskać najlepszą wydajność, użyj tej drugiej. Jest to kluczzastępczy daty i reprezentuje datę utworzenia poprawki lub posiada null
dla aktywnych, niekompletnych poprawek. Jeśli chcesz, aby wszystkie daty od {startDate}
włącznie, dodaj następujący filtr do zapytania.
RevisedDateSK eq null or RevisedDateSK gt {startDateSK}
Na przykład następujące zapytanie zwraca liczbę elementów roboczych dla każdego dnia od początku 2020 roku. Zwróć uwagę, że oprócz oczywistego filtru w DateSK
kolumnie znajduje się drugi filtr dla elementu RevisedDateSK
. Chociaż może się wydawać zbędne, silnik zapytań pomaga odfiltrować wersje, które nie dotyczą zapytania, i znacznie poprawia wydajność zapytań.
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)
)
Uwaga
Wymyśliliśmy to zalecenie podczas pracy nad widżetami Burndown. Początkowo zdefiniowaliśmy tylko filtry dla DateSK
, ale nie mogliśmy uzyskać, aby to zapytanie skalowało się dobrze dla organizacji z dużymi zestawami danych. Podczas profilowania zapytań zauważyliśmy, że DateSK
nie filtruje poprawek. Dopiero po dodaniu filtru na RevisedDateSK
byliśmy w stanie uzyskać doskonałe wyniki na dużą skalę.
~
Zespół produktu
✔️ Używaj cotygodniowych lub miesięcznych migawek dla zapytań dotyczących trendów obejmujących długi okres
Domyślnie wszystkie tabele migawek są modelowane jako tabele faktów migawek dziennych. Jeśli wykonasz zapytanie o zakres czasu, otrzyma wartość dla każdego dnia. Długie zakresy czasu powodują dużą liczbę rekordów. Jeśli nie potrzebujesz takiej wysokiej precyzji, możesz użyć cotygodniowych lub nawet miesięcznych migawek.
Możesz to zrobić za pomocą innych wyrażeń filtru, aby usunąć dni, które nie zakończą danego tygodnia lub miesiąca. Użyj właściwości IsLastDayOfPeriod
, która została dodana do Analytics z myślą o tym scenariuszu. Ta właściwość jest typu Microsoft.VisualStudio.Services.Analytics.Model.Period
i może określić, czy dzień kończy się w różnych okresach (na przykład tygodni, miesięcy itd.).
<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>
Ponieważ Microsoft.VisualStudio.Services.Analytics.Model.Period
jest definiowana jako wyliczenie z flagami, użyj operatora OData has
i określ pełny typ literałów okresu.
IsLastDayOfPeriod has Microsoft.VisualStudio.Services.Analytics.Model.Period'Month'
Na przykład następujące zapytanie zwraca liczbę elementów roboczych zdefiniowanych w ostatnim dniu każdego miesiąca.
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)
)
✔️ Używaj Tags
właściwości kolekcji w elementach roboczych podczas filtrowania według tagów
Możesz użyć TagNames
właściwości z contains
funkcją , aby określić, czy praca została oznaczona określonym tagiem. Takie podejście może jednak spowodować spowolnienie zapytań, zwłaszcza podczas sprawdzania wielu tagów w tym samym czasie. Aby uzyskać najlepszą wydajność i wyniki, użyj właściwości nawigacji Tags
.
Na przykład następujące zapytanie pobiera wszystkie elementy robocze oznaczone tagiem {tag}
.
https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
$filter=Tags/any(t:t/TagName eq '{tag}')
&$select=WorkItemId, Title, State
Takie podejście działa również świetnie, gdy trzeba filtrować wiele tagów. Na przykład następujące zapytanie zwraca wszystkie elementy robocze oznaczone tagiem {tag1}
lub{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
Można również połączyć te filtry z operatorem "and". Na przykład następujące zapytanie pobiera wszystkie elementy robocze, które zostały oznaczone tagami {tag1}
i {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
✔️ TagNames
Użyj właściwości DO, jeśli chcesz wyświetlić wszystkie tagi w elemencie roboczym jako tekst
Właściwość Tags
nawigacji opisana w poprzedniej sekcji doskonale nadaje się do filtrowania. Jednak praca z nimi stanowi pewne wyzwania, ponieważ zapytanie zwraca tagi w zagnieżdżonej kolekcji. Model danych zawiera również właściwość pierwotną TagNames
(Edm.String
), którą dodaliśmy w celu uproszczenia scenariuszy użycia tagów. Jest to pojedyncza wartość tekstowa zawierająca listę wszystkich tagów oddzielonych średnikiem "; ". Użyj tej właściwości, gdy zależy Ci tylko na wyświetlaniu tagów razem. Można połączyć je z opisanymi wcześniej filtrami tagów.
Na przykład, następujące zapytanie pobiera wszystkie elementy pracy oznaczone tagiem {tag}
. Zwraca identyfikator elementu roboczego, tytuł, stan i tekstową reprezentację połączonych tagów.
https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
$filter=Tags/any(t:t/TagName eq '{tag}')
&$select=WorkItemId, Title, State, TagNames
Ważne
Właściwość TagNames
ma limit długości 1024 znaków. Zawiera zestaw tagów pasujących do tego limitu. Jeśli element roboczy ma wiele tagów lub tagi są bardzo długie, TagNames
nie zawiera pełnego zestawu i zamiast tego należy używać właściwości nawigacyjnej Tag
.
❌ NIE używaj funkcji tolower
i toupper
do porównywania bez uwzględnienia wielkości liter
Jeśli pracowałeś z innymi systemami, możesz oczekiwać użycia funkcji tolower
lub toupper
do porównania bez uwzględniania wielkości liter. W przypadku analizy wszystkie porównania ciągów są domyślnie niewrażliwe na wielkość liter, więc nie trzeba stosować żadnych funkcji, aby jawnie je obsłużyć.
Na przykład następujące zapytanie pobiera wszystkie elementy robocze oznaczone etykietą "QUALITY", "quality" lub dowolną inną kombinacją tego słowa.
https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
$filter=Tags/any(t:t/TagName eq 'quality')
&$select=WorkItemId, Title, State, TagNames
❌ NIE używaj nieograniczonego rozszerzania z $levels=max
OData ma możliwość rozszerzenia wszystkich poziomów struktury hierarchicznej. Na przykład śledzenie elementów roboczych zawiera pewne jednostki, w których można zastosować nieograniczone rozszerzenie. Ta operacja działa tylko w przypadku organizacji z niewielką ilością danych. Nie radzi sobie dobrze z większymi zestawami danych. Nie używaj go w ogóle, jeśli:
- Pracujesz z dużymi zestawami danych.
- Tworzysz widżet i nie masz kontroli nad miejscem instalacji widżetu.
✔️ Używaj stronicowania opartego na serwerze
Jeśli poprosisz o zestaw, który jest zbyt duży, aby został wysłany w jednej odpowiedzi, analiza stosuje stronicowanie. Odpowiedź zawiera tylko zestaw częściowy i link umożliwiający pobranie kolejnego częściowego zestawu elementów. Ta strategia jest opisana w specyfikacji OData — OData w wersji 4.0. Część 1: Protokół — serwerowe stronicowanie. Pozwalając usłudze kontrolować stronicowanie, uzyskujesz najlepszą wydajność, ponieważ skiptoken
został starannie zaprojektowany dla każdej jednostki, aby był tak wydajny, jak to możliwe.
Link do następnej strony jest zawarty w właściwości @odata.nextLink
.
{
"@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"}
Uwaga
Większość istniejących klientów OData może automatycznie obsługiwać stronicowanie sterowane serwerem. Na przykład ta strategia jest już używana przez następujące narzędzia: Power BI, SQL Server Integration Services i Azure Data Factory.
❌ NIE używaj opcji zapytania $top
i $skip
do implementowania stronicowania opartego na kliencie
W przypadku innych interfejsów API REST można zaimplementować stronicowanie sterowane przez klienta za pomocą opcji zapytań $top
i $skip
. Nie używaj ich z usługą Analytics. Istnieje kilka problemów z tym podejściem, a wydajność jest jednym z nich. Zamiast tego zastosuj strategię stronicowania opartą na serwerze opisaną w poprzedniej sekcji.
✔️ $top
Użyj opcji kwerendy, aby ograniczyć liczbę rekordów
Opcję kwerendy $top
odradza się tylko wtedy, gdy jest używana razem z $skip
. Jeśli w scenariuszu raportowania potrzebujesz tylko podzestawu rekordów (na przykład przykładu), warto użyć $top
opcji zapytania. Ponadto, jeśli musisz sklasyfikować rekordy zgodnie z pewnymi kryteriami, zawsze należy użyć $top
w połączeniu z $orderby
, aby uzyskać stabilny wynik z rekordami o najwyższej klasyfikacji.
✔️ ROZWAŻ napisanie zapytania w celu zwrócenia niewielkiej liczby rekordów
Pisanie zapytania zwracającego niewielką liczbę rekordów jest najbardziej intuicyjną wskazówką. Zawsze staraj się pobierać tylko dane, o których naprawdę ci zależy. Można to osiągnąć, udostępniając większość zaawansowanych funkcji filtrowania w języku zapytań OData.
✔️ ROZWAŻ ograniczenie liczby wybranych właściwości do minimum
Niektórzy administratorzy projektów w dużym stopniu dostosowują swoje procesy, dodając pola niestandardowe. Znaczne dostosowanie może prowadzić do problemów z wydajnością podczas pobierania wszystkich dostępnych kolumn w rozbudowanych jednostkach (na przykład WorkItems
). Analiza jest oparta na technologii indeksu magazynu kolumnowego. Oznacza to, że zarówno magazynowanie danych, jak i przetwarzanie zapytań są oparte na kolumnach. Dlatego tym więcej właściwości, do których odwołuje się zapytanie, tym droższe jest przetwarzanie. Zawsze staraj się ograniczyć zestaw właściwości w zapytaniach do tego, co naprawdę interesuje Cię w scenariuszu raportowania.
✔️ Rozważ filtrowanie według właściwości klucza zastępczego dla daty (DateSK
sufiks)
Istnieje wiele sposobów definiowania filtru daty. Możesz filtrować według właściwości daty bezpośrednio (na przykład CreatedDate
), jej odpowiednika nawigacyjnego (na przykład CreatedOnDate
), lub jej zastępczej reprezentacji klucza (na przykład CreatedDate
). Ostatnia opcja daje najlepszą wydajność i jest preferowana, gdy zezwalają na to wymagania raportowania.
Na przykład następujące zapytanie zwraca wszystkie elementy robocze utworzone od początku 2020 roku.
https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
$filter=CreatedDateSK ge 20200101
✔️ ROZWAŻ filtrowanie kolumn kluczy zastępczych
Jeśli chcesz filtrować dane dotyczące wartości powiązanego obiektu (na przykład filtrowanie elementu roboczego w nazwie projektu), zawsze masz dwie opcje. Możesz użyć właściwości nawigacji (na przykład Project/ProjectName
) lub przechwycić klucz zastępczy z góry i użyć go bezpośrednio w zapytaniu (na przykład ProjectSK
).
Jeśli tworzysz widżet, zalecamy użycie tej drugiej opcji. Po przekazaniu klucza w ramach zapytania liczba zestawów jednostek, które muszą być dotykane, zostanie zmniejszona, a wydajność się poprawia.
Na przykład następujące zapytanie filtruje WorkItems
, używając właściwości ProjectSK
zamiast właściwości nawigacji Project/ProjectName
.
https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
$filter=ProjectSK eq {projectSK}
❌UNIKAJ używania Parent
, Children
lub Revisions
właściwości w klauzulach $filter
lub $expand
Elementy robocze to najdroższe jednostki w całym modelu danych. Mają one kilka właściwości nawigacji, których można użyć do uzyskiwania dostępu do powiązanych elementów roboczych: Parent
, , Children
Revisions
. Za każdym razem, gdy używasz ich w zapytaniu, spodziewaj się jednak spadku wydajności. Zawsze pytaj, czy naprawdę potrzebujesz jednej z tych właściwości i potencjalnie zaktualizuj projekt.
Na przykład zamiast rozszerzać Parent
, można pobrać więcej zadań i użyć właściwości ParentWorkItemId
aby odtworzyć pełną hierarchię po stronie klienta. Przeprowadź taką optymalizację w każdym przypadku indywidualnie.
✔️ ROZWAŻ przekazanie VSTS.Analytics.MaxSize
preferencji w nagłówku
Podczas wykonywania zapytania nie wiadomo, ile rekordów zwraca zapytanie. Wyślij kolejne zapytanie z agregacjami lub postępuj zgodnie ze wszystkimi kolejnymi linkami i pobierz cały zestaw danych. Analiza uwzględnia VSTS.Analytics.MaxSize
preferencje, pozwalając na szybką reakcję w przypadku niepowodzenia, gdy zestaw danych jest większy niż to, co klient może zaakceptować.
Ta opcja jest przydatna w scenariuszach eksportowania danych. Aby z niego skorzystać, musisz dodać nagłówek Prefer
do żądania HTTP i ustawić VSTS.Analytics.MaxSize
na wartość nieujemną. Wartość VSTS.Analytics.MaxSize
reprezentuje maksymalną liczbę rekordów, które można zaakceptować. Jeśli ustawisz ją na zero, zostanie użyta wartość domyślna 200 K.
Na przykład następujące zapytanie zwraca elementy robocze, jeśli zestaw danych jest mniejszy lub równy 1000 rekordów.
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}
Jeśli zestaw danych przekroczy limit 1000 rekordów, zapytanie natychmiast zakończy się niepowodzeniem z powodu następującego błędu.
Wynik zapytania zawiera 1296 wierszy i przekracza maksymalny dozwolony rozmiar 1000. Zmniejsz liczbę rekordów, stosując dodatkowe filtry
Aby uzyskać informacje na temat ustawiania maksymalnego rozmiaru strony, zobacz właściwość ODataPreferenceHeader.MaxPageSize.
Wskazówki dotyczące stylu zapytania
-
✔️ Należy używać
$count
właściwości wirtualnej w metodach agregacji -
❌ UNIKAJ używania
$count
właściwości wirtualnej w segmencie adresu URL -
❌ UNIKAJ mieszania
$apply
i$filter
klauzul w jednym zapytaniu - ✔️ ROZWAŻ użycie aliasów parametrów, aby oddzielić nietrwałe części zapytania
- ✔️ ROZWAŻ utworzenie struktury zapytania, aby było zgodne z kolejnością oceny OData
- ✔️ ROZWAŻ przejrzenie funkcji OData opisanych w adnotacjach metadanych
✔️ Użyj $count
właściwości wirtualnej w metodach agregacji
Niektóre jednostki uwidaczniają Count
właściwość. Ułatwiają one niektóre scenariusze raportowania, gdy dane zostaną wyeksportowane do innego magazynu. Nie należy jednak używać tych kolumn w agregacjach w zapytaniach OData.
$count
Zamiast tego użyj właściwości wirtualnej.
Na przykład następujące zapytanie zwraca łączną liczbę elementów roboczych.
https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
$apply=aggregate($count as Count)
❌ UNIKAJ używania $count
właściwości wirtualnej w segmencie adresu URL
Mimo że standard OData umożliwia używanie $count
właściwości wirtualnej dla zestawów jednostek (na przykład _odata/v1.0/WorkItems/$count
), nie wszyscy klienci mogą poprawnie interpretować odpowiedź. Dlatego zaleca się, aby zamiast tego używać agregacji.
Na przykład następujące zapytanie zwraca łączną liczbę elementów roboczych.
https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
$apply=aggregate($count as Count)
✔️ ROZWAŻ użycie aliasów parametrów, aby oddzielić nietrwałe części zapytania
Aliasy parametrów zapewniają eleganckie rozwiązanie do wyodrębniania nietrwałych części, takich jak wartości parametrów z głównego tekstu zapytania. Można ich używać w wyrażeniach, które oceniają:
- Wartość pierwotna
- Wartość złożona
- Kolekcja wartości pierwotnych lub złożonych.
Aby uzyskać więcej informacji, zobacz OData w wersji 4.0. Część 2. Konwencje adresów URL — aliasy parametrów 5.1.1.13. Parametry są przydatne, gdy tekst zapytania jest używany jako szablon, który można wypełnić wartościami dostarczonymi przez użytkownika.
Na przykład następujące zapytanie używa @createdDateSK
parametru , aby oddzielić wartość od wyrażenia filtru.
https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
$filter=CreatedDateSK ge @createdDateSK
&$select=WorkItemId, Title, State
&@createdDateSK=20200101
❌ UNIKAJ mieszania $apply
i $filter
klauzul w jednym zapytaniu
Jeśli chcesz dodać filter
do swojego zapytania, masz dwie opcje. Można to zrobić za pomocą klauzuli $filter
lub kombinacji $apply=filter()
. Każda z tych opcji działa świetnie samodzielnie, ale połączenie ich razem może prowadzić do nieoczekiwanych wyników.
Pomimo oczekiwań, które można mieć, OData jasno definiuje kolejność oceny. Ponadto klauzula $apply
ma priorytet nad $filter
. Z tego powodu należy wybrać jedną lub drugą, ale uniknąć tych dwóch opcji filtrowania w jednym zapytaniu. Ważne jest, aby zapytania zostały wygenerowane automatycznie.
Na przykład następujące zapytanie najpierw filtruje elementy robocze według StoryPoint gt 5
, agreguje wyniki według ścieżki, a na koniec filtruje wynik według StoryPoints gt 2
. W tej kolejności oceny zapytanie zawsze zwraca pusty zestaw.
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)
)
✔️ ROZWAŻ utworzenie struktury zapytania, aby było zgodne z kolejnością oceny OData
Ponieważ mieszanie $apply
i filter
klauzul w jednym zapytaniu może prowadzić do potencjalnych nieporozumień, zalecamy utworzenie struktury klauzul zapytania w celu dopasowania ich do kolejności oceny.
$apply
$filter
$orderby
$expand
$select
$skip
$top
✔️ ROZWAŻ przejrzenie funkcji OData opisanych w adnotacjach metadanych
Jeśli nie masz pewności, które funkcje usługi OData obsługuje analiza danych, możesz wyszukać adnotacje w metadanych. Komitet techniczny OASIS Open Data Protocol (OData) w repozytorium GitHub TC utrzymuje listę dostępnych adnotacji.
Na przykład lista obsługiwanych funkcji filtru jest dostępna w Org.OData.Capabilities.V1.FilterFunctions
adnotacji w kontenerze jednostki.
<Annotation Term="Org.OData.Capabilities.V1.FilterFunctions">
<Collection>
<String>contains</String>
<String>endswith</String>
[...]
</Collection>
</Annotation>
Inną przydatną adnotacją jest Org.OData.Capabilities.V1.ExpandRestrictions
, która wyjaśnia, które właściwości nawigacji nie można użyć w klauzuli $expand
. Na przykład poniższa adnotacja wyjaśnia, że Revisions
w WorkItems
zestawie jednostek nie można rozszerzyć.
<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>
Powiązane artykuły
- Konstruowanie zapytań OData na potrzeby analizy
- Wykonywanie zapytań dotyczących danych śledzenia elementów roboczych
- Agregowanie danych
- Wykonywanie zapytań dotyczących danych trendu
- Zapytania dotyczące linków elementów roboczych
- Obsługiwane funkcje i klauzule
- Śledzenie pracy, przetwarzanie i limity projektu