Najlepsze rozwiązania dotyczące zapytań język zapytań Kusto
Dotyczy: ✅Microsoft Fabric✅Azure Data Explorer✅Azure Monitor✅Microsoft Sentinel
Poniżej przedstawiono kilka najlepszych rozwiązań, które należy zastosować, aby przyspieszyć uruchamianie zapytania.
Krótko mówiąc
Akcja | Używanie | Nie używaj | Uwagi |
---|---|---|---|
Zmniejszanie ilości zapytań dotyczących danych | Użyj mechanizmów, takich jak operator, where aby zmniejszyć ilość przetwarzanych danych. |
Aby uzyskać więcej informacji na temat wydajnych sposobów zmniejszenia ilości przetwarzanych danych, zobacz Zmniejszanie ilości przetwarzanych danych. | |
Unikaj używania nadmiarowych odwołań kwalifikowanych | Podczas odwoływania się do jednostek lokalnych użyj niekwalifikowanej nazwy. | Aby uzyskać więcej informacji, zobacz Unikanie używania nadmiarowych kwalifikowanych odwołań. | |
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 | Użycie operatora has . |
Nie używaj contains |
Gdy szukasz pełnych tokenów, działa lepiej, has ponieważ nie szuka podciągów. |
Operatory z uwzględnieniem wielkości liter | Użyj witryny == . |
Nie używaj =~ . |
Użyj operatorów z uwzględnieniem wielkości liter, jeśli jest to możliwe. |
Użyj witryny in . |
Nie używaj in~ . |
||
Użyj witryny contains_cs . |
Nie używaj contains . |
Użycie has /has_cs polecenia jest preferowane do .contains /contains_cs |
|
Wyszukiwanie tekstu | Wyszukaj 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. | Za pomocą tej metody płacisz tylko raz za wyodrębnianie kolumn. | |
Wyszukiwanie rzadkich kluczy/wartości w obiektach dynamicznych | Użyj witryny MyTable | where DynamicColumn has "Rare value" | where DynamicColumn.SomeKey == "Rare value" . |
Nie używaj MyTable | where DynamicColumn.SomeKey == "Rare value" . |
Ta metoda umożliwia filtrowanie większości rekordów i analizowanie tylko w formacie JSON w pozostałej części. |
let instrukcja z wartością używaną więcej niż raz |
Użyj funkcji materialize(). | Aby uzyskać więcej informacji na temat używania metody materialize() , zobacz materialize(). Aby uzyskać więcej informacji, zobacz Optymalizowanie zapytań korzystających z nazwanych wyrażeń. |
|
Stosowanie konwersji typów na więcej niż miliard rekordów | Zmień kształt zapytania, aby zmniejszyć ilość danych wprowadzoną do konwersji. | Nie konwertuj dużych ilości danych, jeśli można ich uniknąć. | |
Nowe zapytania | Użyj limit [small number] polecenia lub count na końcu. |
Uruchamianie niezwiązanych zapytań dotyczących nieznanych zestawów danych może spowodować zwrócenie gigabajtów wyników, co spowoduje powolną odpowiedź i zajęte środowisko. | |
Porównania bez uwzględniania wielkości liter | Użyj witryny Col =~ "lowercasestring" . |
Nie używaj tolower(Col) == "lowercasestring" . |
|
Porównaj dane już z małymi literami (lub wielkimi literami) | Col == "lowercasestring" (lub Col == "UPPERCASESTRING" ). |
Unikaj używania porównań bez uwzględniania wielkości liter. | |
Filtrowanie kolumn | Filtruj według kolumny tabeli. | Nie filtruj według kolumny obliczeniowej. | |
Korzystanie z polecenia T | where predicate(*Expression*) |
Nie używaj T | extend _value = *Expression* | where predicate(_value) |
||
operator summarize | Użyj hint.shufflekey=<key> , gdy group by keys summarize operator ma wysoką kardynalność. |
Wysoka kardynalność jest idealnie ponad milionem. | |
operator sprzężenia | Wybierz tabelę z najmniejszą liczbą wierszy jako pierwszą (najbardziej po lewej stronie w zapytaniu). | ||
Użyj in zamiast lewej części join do filtrowania według pojedynczej kolumny. |
|||
Łączenie między klastrami | Uruchom zapytanie po prawej stronie sprzężenia w środowiskach zdalnych, takich jak klastry lub magazyny zdarzeń, gdzie znajduje się większość danych. | ||
Sprzężenia, gdy lewa strona jest mała, a prawa strona jest duża | Użyj polecenia hint.strategy=broadcast. | Małe odnosi się do maksymalnie 100 megabajtów (MB) danych. | |
Sprzężenia, gdy prawa strona jest mała, a lewa strona jest duża | Użyj operatora wyszukiwania zamiast join operatora |
Jeśli prawa strona odnośnika jest większa niż kilkadziesiąt MB, zapytanie kończy się niepowodzeniem. | |
Sprzężenia, gdy obie strony są zbyt duże | Użyj polecenia hint.shufflekey=<key>. | Użyj polecenia , 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 | Użyj 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 polecenia , gdy przeanalizowane ciągi nie są zgodne z tym samym formatem lub wzorcem. | Wyodrębnij wymagane wartości przy użyciu wyrażenia REGEX. | |
materialize(), funkcja | Wypchnij wszystkie możliwe operatory, które zmniejszają zmaterializowany zestaw danych i nadal zachowują semantykę zapytania. | Na przykład filtry lub tylko wymagane kolumny projektu. Aby uzyskać więcej informacji, zobacz Optymalizowanie zapytań korzystających z nazwanych wyrażeń. | |
Używanie zmaterializowanych widoków | Użyj zmaterializowanych widoków do przechowywania często używanych agregacji. Preferuj materialized_view() używanie funkcji tylko do wykonywania zapytań dotyczących zmaterializowanej części. |
materialized_view('MV') |
Zmniejszanie ilości przetwarzanych danych
Wydajność zapytania zależy bezpośrednio od ilości danych potrzebnych do przetworzenia. Tym mniej danych jest przetwarzanych, tym szybciej wykonuje zapytanie (i tym mniej zasobów zużywa). W związku z tym najważniejszym najlepszym rozwiązaniem jest utworzenie struktury zapytania w taki sposób, aby zmniejszyć ilość przetwarzanych danych.
Uwaga
W poniższej dyskusji ważne jest, aby pamiętać o koncepcji wyboru filtru. Wybierz, jaki procent rekordów jest filtrowany podczas filtrowania według niektórych predykatów. Predykat wysoce selektywny oznacza, że po zastosowaniu predykatu pozostaje tylko kilka rekordów, co zmniejsza ilość danych, które należy następnie efektywnie przetwarzać.
W kolejności ważności:
Odwołują się tylko do tabel, których dane są potrzebne przez zapytanie. Na przykład w przypadku używania
union
operatora z odwołaniami do tabeli wieloznacznej lepiej jest od punktu wydajności odwoływać się tylko do kilku tabel, zamiast odwoływać się do kilku tabel, zamiast 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 kolejność umieszczania predykatów, niezależnie od tego, czy używasz jednegowhere
operatora, czy wielu kolejnychwhere
operatorów, może mieć znaczący wpływ na wydajność zapytania.Najpierw zastosuj predykaty całego fragmentu. Oznacza to, że należy najpierw zastosować predykaty korzystające z funkcji extent_id() i funkcji extent_tags(). Ponadto w przypadku selektywnych predykatów, które zawężają dane do określonych partycji, należy je najpierw zastosować.
Następnie zastosuj predykaty, które działają na
datetime
kolumnach tabeli. Usługa Kusto zawiera wydajny indeks dla takich kolumn, często całkowicie eliminując całe fragmenty danych bez konieczności uzyskiwania dostępu do tych fragmentów.Następnie zastosuj predykaty, które działają na
string
kolumnach idynamic
, zwłaszcza takie predykaty, które mają zastosowanie na poziomie terminów. Porządkowanie predykatów według selektora. Na przykład wyszukiwanie identyfikatora użytkownika, gdy miliony użytkowników są wysoce selektywne i zwykle obejmuje wyszukiwanie terminów, dla których indeks jest bardzo wydajny.Następnie zastosuj predykaty, które są selektywne i są oparte na kolumnach liczbowych.
Na koniec w przypadku zapytań, które skanują dane kolumny tabeli (na przykład w przypadku predykatów, takich jak
contains
"@!@!"
, które nie mają terminów i nie korzystają z indeksowania), należy najpierw uporządkować predykaty, które skanują kolumny z mniejszymi danymi. Zmniejsza to konieczność dekompresowania i skanowania dużych kolumn.
Unikaj używania nadmiarowych odwołań kwalifikowanych
Odwołania do jednostek, takich jak tabele i zmaterializowane widoki według nazwy.
Na przykład tabela T
może być przywoływany jako po prostu T
(niekwalifikowana nazwa) lub przy użyciu kwalifikatora bazy danych (na przykładdatabase("DB").T
, gdy tabela znajduje się w bazie danych o nazwie DB
), lub przy użyciu w pełni kwalifikowanej nazwy (na przykład cluster("<serviceURL>").database("DB").T
).
Na przykład tabela T
może być przywoływany jako po prostu T
(niekwalifikowana nazwa) lub przy użyciu kwalifikatora bazy danych (na przykładdatabase("DB").T
, gdy tabela znajduje się w bazie danych o nazwie DB
), lub przy użyciu w pełni kwalifikowanej nazwy (na przykład cluster("X.Y.kusto.windows.net").database("DB").T
).
Najlepszym rozwiązaniem jest unikanie używania kwalifikacji nazw, gdy są nadmiarowe, z następujących powodów:
Niekwalifikowane nazwy są łatwiejsze do zidentyfikowania (dla czytelnika ludzkiego) jako należącego do zakresu bazy danych.
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.
Jest to szczególnie istotne w przypadku, gdy te bazy danych znajdują się w innym klastrze.
Dotyczy to szczególnie sytuacji, gdy te bazy danych znajdują się w innej usłudze Eventhouse.
Unikanie kwalifikowanych nazw ułatwia czytelnikowi wykonywanie odpowiednich czynności.
Uwaga
Nie oznacza to, że kwalifikowane nazwy są złe dla wydajności. W większości przypadków usługa Kusto może zidentyfikować, kiedy w pełni kwalifikowana nazwa odwołuje się do jednostki należącej do zakresu bazy danych i "zwarć" zapytania, tak aby nie było traktowane jako zapytanie obejmujące wiele klastrów. Jednak nie zalecamy polegania na tym, jeśli nie jest to konieczne.
Uwaga
Nie oznacza to, że kwalifikowane nazwy są złe dla wydajności. W większości przypadków usługa Kusto może zidentyfikować, kiedy w pełni kwalifikowana nazwa odwołuje się do jednostki należącej do zakresu bazy danych. Jednak nie zalecamy polegania na tym, jeśli nie jest to konieczne.