Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Dotyczy: ✅Microsoft Fabric✅Azure Data Explorer✅Azure Monitor✅Microsoft Sentinel
Załóżmy, że chcesz obliczyć liczbę unikatowych użytkowników każdego dnia w ciągu ostatnich siedmiu dni. Można uruchomić summarize dcount(user) raz dziennie z zakresem filtrowany do ostatnich siedmiu dni. Ta metoda jest nieefektywna, ponieważ za każdym razem, gdy obliczanie jest uruchamiane, istnieje sześć dni nakładających się na poprzednie obliczenie. Można również obliczyć agregację dla każdego dnia, a następnie połączyć te agregacje. Ta metoda wymaga "zapamiętania" ostatnich sześciu wyników, ale jest o wiele bardziej wydajna.
Partycjonowanie zapytań zgodnie z opisem jest łatwe w przypadku prostych agregacji, takich jak count() i sum(). Może być również przydatny w przypadku złożonych agregacji, takich jak dcount() i percentiles(). W tym artykule wyjaśniono, jak usługa Kusto obsługuje takie obliczenia.
W poniższych przykładach pokazano, jak używać hll/tdigest i demonstrować, że użycie tych poleceń jest wysoce wydajne w niektórych scenariuszach:
Ważne
Wyniki hll, tdigesthll_ifhll_mergei tdigest_merge są obiektami typudynamic, które mogą być następnie przetwarzane przez inne funkcje (dcount_hll, percentile_tdigest, percentiles_array_tdigest, i ).percentrank_tdigest Kodowanie tego obiektu może ulec zmianie w czasie (na przykład z powodu uaktualnienia oprogramowania); jednak takie zmiany zostaną wprowadzone w sposób zgodny z poprzednimi wersjami, dzięki czemu można trwale przechowywać takie wartości i odwoływać się do nich w zapytaniach niezawodnie.
Uwaga
W niektórych przypadkach obiekty dynamiczne generowane przez hll funkcje agregujące lub tdigest mogą być duże i przekraczają domyślną właściwość MaxValueSize w zasadach kodowania. Jeśli tak, obiekt zostanie pozyskany jako null.
Na przykład w przypadku utrwalania danych wyjściowych hll funkcji o poziomie dokładności 4 rozmiar hll obiektu przekracza wartość domyślną MaxValueSize, czyli 1 MB.
Aby uniknąć tego problemu, zmodyfikuj zasady kodowania kolumny, jak pokazano w poniższych przykładach.
range x from 1 to 1000000 step 1
| summarize hll(x,4)
| project sizeInMb = estimate_data_size(hll_x) / pow(1024,2)
Wyjście
| sizeInMb |
|---|
| 1.0000524520874 |
Pozyskiwanie tego obiektu do tabeli przed zastosowaniem tego rodzaju zasad spowoduje pozyskiwanie wartości null:
.set-or-append MyTable <| range x from 1 to 1000000 step 1
| summarize hll(x,4)
MyTable
| project isempty(hll_x)
Wyjście
| Column1 |
|---|
| 1 |
Aby uniknąć pozyskiwania wartości null, użyj specjalnego typu bigobjectzasad kodowania , który zastępuje MaxValueSize wartość do 2 MB w następujący sposób:
.alter column MyTable.hll_x policy encoding type='bigobject'
Pozyskiwanie wartości teraz do tej samej tabeli powyżej:
.set-or-append MyTable <| range x from 1 to 1000000 step 1
| summarize hll(x,4)
Pozyskuje drugą wartość pomyślnie:
MyTable
| project isempty(hll_x)
Wyjście
| Column1 |
|---|
| 1 |
| 0 |
Przykład: liczba z binned sygnaturą czasowa
Istnieje tabela zawierająca PageViewsHllTDigesthll wartości stron wyświetlanych w każdej godzinie. Te wartości mają być binned do 12h. hll Scal wartości przy użyciu funkcji agregującej z sygnaturą hll_merge() czasową binned na 12h. Użyj funkcji dcount_hll , aby zwrócić wartość końcową dcount :
PageViewsHllTDigest
| summarize merged_hll = hll_merge(hllPage) by bin(Timestamp, 12h)
| project Timestamp , dcount_hll(merged_hll)
Wyjście
| Sygnatura czasowa | dcount_hll_merged_hll |
|---|---|
| 2016-05-01 12:00:00.0000000 | 20056275 |
| 2016-05-02 00:00:00.0000000 | 38797623 |
| 2016-05-02 12:00:00.0000000 | 39316056 |
| 2016-05-03 00:00:00.0000000 | 13685621 |
Aby bin timestamp for 1d:
PageViewsHllTDigest
| summarize merged_hll = hll_merge(hllPage) by bin(Timestamp, 1d)
| project Timestamp , dcount_hll(merged_hll)
Wyjście
| Sygnatura czasowa | dcount_hll_merged_hll |
|---|---|
| 2016-05-01 00:00:00.0000000 | 20056275 |
| 2016-05-02 00:00:00.0000000 | 64135183 |
| 2016-05-03 00:00:00.0000000 | 13685621 |
To samo zapytanie można wykonać względem wartości tdigest, które reprezentują BytesDelivered wartość w każdej godzinie:
PageViewsHllTDigest
| summarize merged_tdigests = merge_tdigest(tdigestBytesDel) by bin(Timestamp, 12h)
| project Timestamp , percentile_tdigest(merged_tdigests, 95, typeof(long))
Wyjście
| Sygnatura czasowa | percentile_tdigest_merged_tdigests |
|---|---|
| 2016-05-01 12:00:00.0000000 | 170200 |
| 2016-05-02 00:00:00.0000000 | 152975 |
| 2016-05-02 12:00:00.0000000 | 181315 |
| 2016-05-03 00:00:00.0000000 | 146817 |
Przykład: tabela tymczasowa
Limity usługi Kusto są osiągane w przypadku zestawów danych, które są zbyt duże, gdzie należy uruchamiać okresowe zapytania w zestawie danych, ale uruchamiać regularne zapytania, aby obliczyć percentile() lub dcount() za pośrednictwem dużych zestawów danych.
Aby rozwiązać ten problem, nowo dodane dane mogą zostać dodane do tabeli tymczasowej jako hll lub wartości używanehll(), gdy wymagana operacja jest dcount lub tdigest() gdy wymagana operacja jest percentylem przy użyciu set/append lub update policytdigest . W takim przypadku wyniki dcount pośrednie lub tdigest są zapisywane w innym zestawie danych, który powinien być mniejszy niż docelowy duży.
Aby rozwiązać ten problem, nowo dodane dane mogą zostać dodane do tabeli tymczasowej jako hll lub wartości używanehll(), gdy wymagana operacja to dcounttdigest . W takim przypadku wyniki dcount pośrednie są zapisywane w innym zestawie danych, który powinien być mniejszy niż docelowy duży.
Jeśli musisz uzyskać końcowe wyniki tych wartości, zapytania mogą używać hll/tdigest fuzji: . hll-merge()/tdigest_merge() Następnie po pobraniu scalonych wartości może zostać wywołana na tych scalonych wartościach, percentile_tdigest() / dcount_hll() aby uzyskać końcowy wynik dcount lub percentylów.
Zakładając, że istnieje tabela, PageViews, do której dane są pozyskiwane codziennie, każdego dnia, w którym chcesz obliczyć odrębną liczbę stron wyświetlanych na minutę później niż data = datetime(2016-05-01 18:00:00.0000000).
Uruchom poniższe zapytanie:
PageViews
| where Timestamp > datetime(2016-05-01 18:00:00.0000000)
| summarize percentile(BytesDelivered, 90), dcount(Page,2) by bin(Timestamp, 1d)
Wyjście
| Sygnatura czasowa | percentile_BytesDelivered_90 | dcount_Page |
|---|---|---|
| 2016-05-01 00:00:00.0000000 | 83634 | 20056275 |
| 2016-05-02 00:00:00.0000000 | 82770 | 64135183 |
| 2016-05-03 00:00:00.0000000 | 72920 | 13685621 |
To zapytanie agreguje wszystkie wartości za każdym razem, gdy uruchamiasz to zapytanie (na przykład jeśli chcesz uruchomić je wiele razy dziennie).
Jeśli zapiszesz hll wartości i tdigest (które są pośrednimi wynikami dcount i percentylem) w tabeli tymczasowej, PageViewsHllTDigestprzy użyciu zasad aktualizacji lub zestaw/dołączanie poleceń, możesz scalić tylko wartości, a następnie użyć dcount_hll/percentile_tdigest następującego zapytania:
PageViewsHllTDigest
| summarize percentile_tdigest(merge_tdigest(tdigestBytesDel), 90), dcount_hll(hll_merge(hllPage)) by bin(Timestamp, 1d)
Wyjście
| Sygnatura czasowa | percentile_tdigest_merge_tdigests_tdigestBytesDel |
dcount_hll_hll_merge_hllPage |
|---|---|---|
| 2016-05-01 00:00:00.0000000 | 84224 | 20056275 |
| 2016-05-02 00:00:00.0000000 | 83486 | 64135183 |
| 2016-05-03 00:00:00.0000000 | 72247 | 13685621 |
To zapytanie powinno być bardziej wydajne, ponieważ jest uruchamiane w mniejszej tabeli. W tym przykładzie pierwsze zapytanie jest uruchamiane na rekordach ok. 215 mln, podczas gdy drugi jest uruchamiany w ciągu zaledwie 32 rekordów:
Przykład: Wyniki pośrednie
Zapytanie przechowywania. Załóżmy, że masz tabelę podsumowującą, kiedy każda strona Wikipedii została wyświetlona (rozmiar próbki to 10 M), a chcesz znaleźć dla każdej daty1 daty2 procent stron przeglądanych zarówno w kolumnie date1, jak i date2 względem stron wyświetlanych w dniu 1 (data1 data1 < ).
Trywialny sposób używa operatorów sprzężenia i podsumowania:
// Get the total pages viewed each day
let totalPagesPerDay = PageViewsSample
| summarize by Page, Day = startofday(Timestamp)
| summarize count() by Day;
// Join the table to itself to get a grid where
// each row shows foreach page1, in which two dates
// it was viewed.
// Then count the pages between each two dates to
// get how many pages were viewed between date1 and date2.
PageViewsSample
| summarize by Page, Day1 = startofday(Timestamp)
| join kind = inner
(
PageViewsSample
| summarize by Page, Day2 = startofday(Timestamp)
)
on Page
| where Day2 > Day1
| summarize count() by Day1, Day2
| join kind = inner
totalPagesPerDay
on $left.Day1 == $right.Day
| project Day1, Day2, Percentage = count_*100.0/count_1
Wyjście
| Dzień1 | Dzień2 | Procent |
|---|---|---|
| 2016-05-01 00:00:00.0000000 | 2016-05-02 00:00:00.0000000 | 34.0645725975255 |
| 2016-05-01 00:00:00.0000000 | 2016-05-03 00:00:00.0000000 | 16.618368960101 |
| 2016-05-02 00:00:00.0000000 | 2016-05-03 00:00:00.0000000 | 14.6291376489636 |
Powyższe zapytanie trwało ok. 18 sekund.
Jeśli używasz hll()funkcji , hll_merge()i dcount_hll() , równoważne zapytanie zakończy się po ok. 1,3 sekundy i pokaże, że hll funkcje przyspieszają powyższe zapytanie o ~14 razy:
let Stats=PageViewsSample | summarize pagehll=hll(Page, 2) by day=startofday(Timestamp); // saving the hll values (intermediate results of the dcount values)
let day0=toscalar(Stats | summarize min(day)); // finding the min date over all dates.
let dayn=toscalar(Stats | summarize max(day)); // finding the max date over all dates.
let daycount=tolong((dayn-day0)/1d); // finding the range between max and min
Stats
| project idx=tolong((day-day0)/1d), day, pagehll
| mv-expand pidx=range(0, daycount) to typeof(long)
// Extend the column to get the dcount value from hll'ed values for each date (same as totalPagesPerDay from the above query)
| extend key1=iff(idx < pidx, idx, pidx), key2=iff(idx < pidx, pidx, idx), pages=dcount_hll(pagehll)
// For each two dates, merge the hll'ed values to get the total dcount over each two dates,
// This helps to get the pages viewed in both date1 and date2 (see the description below about the intersection_size)
| summarize (day1, pages1)=arg_min(day, pages), (day2, pages2)=arg_max(day, pages), union_size=dcount_hll(hll_merge(pagehll)) by key1, key2
| where day2 > day1
// To get pages viewed in date1 and also date2, look at the merged dcount of date1 and date2, subtract it from pages of date1 + pages on date2.
| project pages1, day1,day2, intersection_size=(pages1 + pages2 - union_size)
| project day1, day2, Percentage = intersection_size*100.0 / pages1
Wyjście
| dzień1 | dzień2 | Procent |
|---|---|---|
| 2016-05-01 00:00:00.0000000 | 2016-05-02 00:00:00.0000000 | 33.2298494510578 |
| 2016-05-01 00:00:00.0000000 | 2016-05-03 00:00:00.0000000 | 16.9773830213667 |
| 2016-05-02 00:00:00.0000000 | 2016-05-03 00:00:00.0000000 | 14.5160020350006 |
Uwaga
Wyniki zapytań nie są dokładne w 100% z powodu błędu hll funkcji. Aby uzyskać więcej informacji na temat błędów, zobacz dcount().