Najlepsze rozwiązania dotyczące zapytań język zapytań Kusto

Poniżej przedstawiono kilka najlepszych rozwiązań, które należy wykonać, aby przyspieszyć uruchamianie zapytania.

Krótko mówiąc

Akcja Zastosowanie Nie używaj Uwagi
Zmniejsz ilość zapytań dotyczących danych Użyj mechanizmów, takich jak where operator, aby zmniejszyć ilość przetwarzanych danych. Zobacz poniżej, aby uzyskać wydajne sposoby zmniejszenia ilości przetwarzanych danych.
Unikaj używania nadmiarowych kwalifikowanych odwołań Podczas odwoływania się do jednostek lokalnych użyj nazwy niekwalifikowanej. Zobacz poniżej, aby uzyskać więcej informacji na ten temat.
datetime Kolumny datetime Użyj typu danych. Nie używaj long typu danych. W zapytaniach nie używaj funkcji konwersji czasu systemu UNIX, takich jak unixtime_milliseconds_todatetime(). Zamiast tego użyj zasad aktualizacji, aby przekonwertować czas systemu UNIX na typ danych podczas pozyskiwania datetime .
Operatory ciągów Korzystanie z has operatora Nie używaj contains Gdy szukasz pełnych tokenów, działa lepiej, has ponieważ nie szuka podciągów.
Operatory uwzględniające wielkość liter Korzystanie z polecenia == Nie używaj =~ Używaj operatorów uwzględniających wielkość liter, jeśli jest to możliwe.
Korzystanie z polecenia in Nie używaj in~
Korzystanie z polecenia contains_cs Nie używaj contains Jeśli możesz użyć has/has_cs polecenia i nie używać contains/contains_cspolecenia , jest to jeszcze lepsze.
Wyszukiwanie tekstu Wyszukiwanie w określonej kolumnie Nie używaj * * wykonuje wyszukiwanie pełnotekstowe we wszystkich kolumnach.
Wyodrębnianie pól z obiektów dynamicznych w milionach wierszy Zmaterializuj kolumnę w czasie pozyskiwania, jeśli większość zapytań wyodrębnia pola z obiektów dynamicznych w milionach wierszy. W ten sposób płacisz tylko raz za wyodrębnianie kolumn.
Wyszukiwanie rzadkich kluczy/wartości w obiektach dynamicznych Korzystanie z polecenia MyTable | where DynamicColumn has "Rare value" | where DynamicColumn.SomeKey == "Rare value" Nie używaj MyTable | where DynamicColumn.SomeKey == "Rare value" W ten sposób odfiltrujesz większość rekordów i wykonujesz analizowanie kodu JSON tylko w pozostałej części.
let instrukcja z wartością używaną więcej niż raz Używanie funkcji materialize() Aby uzyskać więcej informacji na temat używania materialize()metody , zobacz materialize(). Aby uzyskać więcej informacji, zobacz Optymalizowanie zapytań używających nazwanych wyrażeń.
Stosowanie konwersji na ponad 1 miliard rekordów Zmień kształt zapytania, aby zmniejszyć ilość danych podawanych do konwersji. Nie konwertuj dużych ilości danych, jeśli można go uniknąć.
Nowe zapytania Użyj limit [small number] lub count na końcu. Uruchamianie niezwiązanych zapytań dotyczących nieznanych zestawów danych może spowodować zwrócenie wyników do klienta, co powoduje powolne reagowanie i zajęty klaster.
Porównania bez uwzględniania wielkości liter Korzystanie z polecenia Col =~ "lowercasestring" Nie używaj tolower(Col) == "lowercasestring"
Porównaj dane już w małych literach (lub wielkie litery) Col == "lowercasestring" (lub Col == "UPPERCASESTRING") Unikaj używania porównań bez uwzględniania wielkości liter.
Filtrowanie kolumn Filtruj w kolumnie tabeli. Nie filtruj w kolumnie obliczeniowej.
Korzystanie z polecenia T | where predicate(*Expression*) Nie używaj T | extend _value = *Expression* | where predicate(_value)
operator podsumowania Użyj klawisza hint.shufflekey=<key> , gdy group by keys operator podsumowania ma wysoką kardynalność. Wysoka kardynalność jest najlepiej powyżej 1 miliona.
operator sprzężenia Wybierz tabelę z mniejszą liczbą wierszy, która ma być pierwszą (większość w zapytaniu po lewej stronie).
Użyj in zamiast lewej części join do filtrowania według pojedynczej kolumny.
Łączenie między klastrami W klastrach uruchom zapytanie po prawej stronie sprzężenia, gdzie znajduje się większość danych.
Sprzężenia, gdy lewa strona jest mała, a prawa strona jest duża Użyj metody hint.strategy=broadcast Mały odnosi się do maksymalnie 100 MB danych.
Sprzężenia, gdy po prawej stronie jest mała, a lewa strona jest duża Użyj operatora odnośnikajoin zamiast operatora Jeśli prawa strona odnośnika jest większa niż kilkadziesiąt mb/s, zapytanie zakończy się niepowodzeniem.
Sprzężenia, gdy obie strony są zbyt duże Użyj polecenia hint.shufflekey=<key> Użyj, gdy klucz sprzężenia ma wysoką kardynalność.
Wyodrębnianie wartości w kolumnie z ciągami, które współdzielą ten sam format lub wzorzec Korzystanie z operatora analizy Nie używaj kilku extract() instrukcji. Na przykład wartości, takie jak "Time = <time>, ResourceId = <resourceId>, Duration = <duration>, ...."
extract(), funkcja Użyj, gdy przeanalizowane ciągi nie są zgodne z tym samym formatem ani wzorcem. Wyodrębnij wymagane wartości przy użyciu wyrażenia REGEX.
materialize(), funkcja Wypchnij wszystkie możliwe operatory, które będą zmniejszać zmaterializowany zestaw danych i nadal zachować semantyka zapytania. Na przykład filtry lub tylko wymagane kolumny projektu. Aby uzyskać więcej informacji, zobacz Optymalizowanie zapytań używających nazwanych wyrażeń.
Używanie zmaterializowanych widoków Użyj zmaterializowanych widoków do przechowywania często używanych agregacji. Preferuj używanie funkcji do wysyłania zapytań tylko do zmaterializowanej materialized_view() części materialized_view('MV')

Zmniejszanie ilości przetwarzanych danych

Wydajność zapytania zależy bezpośrednio od ilości danych potrzebnych do przetworzenia. Mniej danych jest przetwarzanych, tym szybciej zapytanie (i mniejsza ilość zużywanych zasobów). Dlatego najważniejszym najlepszym rozwiązaniem jest struktura zapytania w taki sposób, aby zmniejszyć ilość przetwarzanych danych.

Uwaga

W poniższej dyskusji ważne jest, aby pamiętać o koncepcji selektywności filtru. W przypadku filtrowania według predykatu wybierana jest wartość procentowa rekordów, które są filtrowane. Predykat wysoce selektywny oznacza, że po zastosowaniu predykatu pozostaje tylko kilka rekordów, co zmniejsza ilość danych, które muszą zostać skutecznie przetworzone.

W kolejności ważności:

  • Kwerenda odwołuje się tylko do tabel, których dane są potrzebne. Na przykład w przypadku używania union operatora z odwołaniami do tabeli z symbolami wieloznacznymi lepiej jest od punktu wydajności odwoływać się tylko do kilku tabel, zamiast używać symbolu wieloznacznego (*), aby odwoływać się do wszystkich tabel, a następnie filtrować dane przy użyciu predykatu w nazwie tabeli źródłowej.

  • Skorzystaj z zakresu danych tabeli, jeśli zapytanie jest istotne tylko dla określonego zakresu. Funkcja table() zapewnia wydajny sposób wyeliminowania danych przez określenie zakresu zgodnie z zasadami buforowania (parametr DataScope).

  • where Zastosuj operator zapytania bezpośrednio po odwołaniach do tabeli.

  • W przypadku korzystania z where operatora zapytania rozsądne użycie kolejności predykatów (w jednym operatorze lub z wieloma kolejnymi operatorami nie ma znaczenia, co) może mieć znaczący wpływ na wydajność zapytania, jak wyjaśniono poniżej.

  • Najpierw zastosuj predykaty całego fragmentu. Oznacza to, że predykaty używające funkcji extent_id() powinny być stosowane najpierw, podobnie jak predykaty używające funkcji extent_tags() i predykatów, które są bardzo selektywne względem partycji danych tabeli (jeśli zdefiniowano).

  • Następnie zastosuj predykaty, które działają na datetime kolumnach tabeli. Usługa Kusto zawiera bardzo wydajny indeks dla takich kolumn, często eliminując całe fragmenty danych całkowicie bez konieczności uzyskiwania dostępu do tych fragmentów.

  • Następnie zastosuj predykaty, które działają na string kolumnach i dynamic , zwłaszcza takie predykaty, które mają zastosowanie na poziomie terminów. Predykaty powinny być uporządkowane według selektywności (na przykład wyszukiwanie identyfikatora użytkownika, gdy miliony użytkowników jest bardzo selektywne i zwykle jest wyszukiwane terminy, dla których indeks jest bardzo wydajny).

  • Następnie zastosuj predykaty, które są selektywne i oparte na kolumnach liczbowych.

  • Na koniec w przypadku zapytań, które skanują dane kolumny tabeli (na przykład w przypadku predykatów, takich jak "zawiera "@!@!", które nie mają terminów i nie korzystają z indeksowania), należy najpierw uporządkować predykaty tak, aby te, które skanują kolumny z mniejszą ilością danych. Zmniejsza to konieczność dekompresowania i skanowania dużych kolumn.

Unikaj używania nadmiarowych kwalifikowanych odwołań

Jednostki, takie jak tabele i zmaterializowane widoki, są przywołyane według nazwy. Na przykład tabela T może być przywoływany jako po prostu T ( niekwalifikowana nazwa) lub za pomocą kwalifikatora bazy danych (np. database("DB").T gdy tabela znajduje się w bazie danych o nazwie DB) lub przy użyciu w pełni kwalifikowanej nazwy (np. cluster("X.Y.kusto.windows.net").database("DB").T).

Najlepszym rozwiązaniem jest unikanie używania kwalifikacji nazw, gdy są one nadmiarowe, z następujących powodów:

  1. Niekwalifikowane nazwy są łatwiejsze do zidentyfikowania (dla czytelnika przez człowieka) jako należącego do zakresu bazy danych.

  2. Odwoływanie się do jednostek w zakresie bazy danych jest zawsze co najmniej tak szybkie, a w niektórych przypadkach znacznie szybsze, a następnie jednostki należące do innych baz danych (zwłaszcza gdy te bazy danych znajdują się w innym klastrze). Unikanie kwalifikowanych nazw pomaga czytelnikowi zrobić to, co należy.

Uwaga

To nie znaczy, że kwalifikowane nazwy są złe dla wydajności. W większości przypadków usługa Kusto jest w stanie określić, kiedy w pełni kwalifikowana nazwa odwołuje się do jednostki należącej do zakresu bazy danych i "zwarć", aby zapytanie nie było traktowane jako zapytanie obejmujące wiele klastrów. Jednak zalecamy, aby nie polegać na tym, jeśli nie jest to konieczne, ze względów określonych powyżej.