Bewährte Methoden für Kusto-Abfragesprache Abfragen

Es stehen einige bewährte Methoden zur Verfügung, damit die Abfrage schneller ausgeführt wird.

Kurzum:

Aktion Verwenden Nicht verwenden Notizen
Verringern der abgefragten Datenmenge Verwenden Sie Mechanismen wie den where -Operator, um die Menge der verarbeiteten Daten zu reduzieren. Im Folgenden finden Sie effiziente Möglichkeiten zum Reduzieren der verarbeiteten Datenmenge.
Vermeiden der Verwendung redundant qualifizierter Verweise Wenn Sie auf lokale Entitäten verweisen, verwenden Sie den nicht qualifizierten Namen. Weitere Informationen zum Thema finden Sie weiter unten.
datetime Spalten Verwenden Sie den Datentyp datetime. Verwenden Sie nicht den long Datentyp. Verwenden Sie in Abfragen keine Unix-Zeitkonvertierungsfunktionen wie unixtime_milliseconds_todatetime(). Verwenden Sie stattdessen Updaterichtlinien, um die UNIX-Zeit während der Erfassung in den datetime Datentyp zu konvertieren.
Zeichenfolgenoperatoren Verwenden Sie den has-Operator Verwenden Sie nicht contains. Bei der Suche nach vollständigen Token funktioniert has besser, da keine Teilzeichenfolgen gesucht werden.
Operatoren, die zwischen Groß- und Kleinschreibung unterscheiden Verwenden Sie == Verwenden Sie nicht =~. Verwenden Sie nach Möglichkeit Operatoren, die zwischen Groß- und Kleinschreibung unterscheiden.
Verwenden Sie in Verwenden Sie nicht in~.
Verwenden Sie contains_cs Verwenden Sie nicht contains. Wenn Sie has/has_cs verwenden können und contains/contains_cs nicht verwenden, ist dies noch besser.
Durchsuchen von Text Suchen in einer bestimmten Spalte Verwenden Sie nicht *. * führt eine Volltextsuche über alle Spalten hinweg durch.
Extrahieren von Feldern aus dynamischen Objekten in Millionen von Zeilen Materialisieren Sie die Spalte zur Erfassungszeit, wenn die meisten Ihrer Abfragen Felder aus dynamischen Objekten aus Millionen von Zeilen extrahieren. Auf diese Weise fällt die Spaltenextraktion nur ein Mal an.
Lookup für seltene Schlüssel/Werte in dynamischen Objekten Verwenden Sie MyTable | where DynamicColumn has "Rare value" | where DynamicColumn.SomeKey == "Rare value" Verwenden Sie nicht MyTable | where DynamicColumn.SomeKey == "Rare value". Auf diese Weise werden die meisten Datensätze herausgefiltert, und die JSON-Analyse wird nur für den Rest ausgeführt.
let-Anweisung mit einem Wert, den Sie mehrmals verwenden Verwenden Sie die materialize()-Funktion. Weitere Informationen zur Verwendung von materialize() finden Sie unter materialize(). Weitere Informationen finden Sie unter Optimieren von Abfragen, die benannte Ausdrücke verwenden.
Anwenden von Konvertierungen auf mehr als 1 Milliarde Datensätze Strukturieren Sie die Abfrage neu, um die Datenmenge zu reduzieren, die in die Konvertierung eingespeist wird. Konvertieren Sie keine großen Datenmengen, wenn dies vermieden werden kann.
Neue Abfragen Verwenden Sie limit [small number] oder count am Ende. Das Ausführen von ungebundenen Abfragen über unbekannte Datasets kann zu GBs von Ergebnissen führen, die an den Client zurückgegeben werden sollen, was zu einer langsamen Antwort und einem ausgelasteten Cluster führt.
Vergleiche ohne Unterscheidung von Groß-/Kleinschreibung Verwenden Sie Col =~ "lowercasestring" Verwenden Sie nicht tolower(Col) == "lowercasestring".
Vergleichen von Daten in Kleinbuchstaben (oder Großbuchstaben) Col == "lowercasestring" (oder Col == "UPPERCASESTRING") Vermeiden Sie die Verwendung von Vergleichen,die keine Groß-/Kleinschreibung berücksichtigen.
Filtern nach Spalten Filtern Sie nach einer Tabellenspalte. Filtern Sie nicht nach einer berechneten Spalte.
Verwenden Sie T | where predicate(*Expression*) Verwenden Sie nicht T | extend _value = *Expression* | where predicate(_value).
summarize-Operator Verwenden Sie hint.shufflekey=<key> , wenn der group by keys des summarize-Operators eine hohe Kardinalität aufweist. Hohe Kardinalität liegt idealerweise über 1 Million.
join-Operator Wählen Sie die Tabelle mit weniger Zeilen aus, die die erste Tabelle sein soll (in der Abfrage ganz links).
Verwenden Sie in anstelle des linken Semis join , um nach einer einzelnen Spalte zu filtern.
Join über Cluster hinweg Führen Sie die Abfrage über Cluster hinweg auf der „rechten“ Seite des Joins aus, auf der sich die meisten Daten befinden.
Join, wenn die linke Seite klein und die rechte Seite groß ist Verwenden Sie hint.strategy=broadcast. Klein bezieht sich auf bis zu 100 MB Daten.
Join, wenn die rechte Seite klein und die linke Seite groß ist Verwenden des Nachschlageoperators anstelle des join Operators Wenn die rechte Seite des Nachschlagevorgangs größer als mehrere zehn MB ist, schlägt die Abfrage fehl.
Join, wenn beide Seiten zu groß sind Verwenden von hint.shufflekey=<key> Verwenden Sie diese Option, wenn der Joinschlüssel über hohe Kardinalität verfügt.
Extrahieren von Werten in einer Spalte mit Zeichenfolgen, die dasselbe Format oder Muster aufweisen Verwenden Sie den parse-Operator. Verwenden Sie nicht mehrere extract()-Anweisungen. Beispielwerte Werte wie "Time = <time>, ResourceId = <resourceId>, Duration = <duration>, ....".
extract()-Funktion Verwenden Sie diese Option, wenn nicht alle analysierten Zeichenfolgen dem gleichen Format oder Muster folgen. Extrahieren Sie die erforderlichen Werte mithilfe von REGEX.
materialize()-Funktion Pushen Sie alle möglichen Operatoren, die das materialisierte Dataset reduzieren und weiterhin die Semantik der Abfrage beibehalten. Beispielsweise Filter oder projekteigene erforderliche Spalten. Weitere Informationen finden Sie unter Optimieren von Abfragen, die benannte Ausdrücke verwenden.
Verwenden von materialisierten Sichten Verwenden Sie materialisierte Sichten zum Speichern häufig verwendeter Aggregationen. Verwenden der materialized_view() Funktion nur zum Abfragen materialisierter Teile materialized_view('MV')

Reduzieren der Verarbeiteten Datenmenge

Die Leistung einer Abfrage hängt direkt von der Datenmenge ab, die verarbeitet werden muss. Je weniger Daten verarbeitet werden, desto schneller die Abfrage (und desto weniger Ressourcen werden verbraucht). Daher besteht die wichtigste bewährte Methode darin, die Abfrage so zu strukturieren, dass die verarbeitete Datenmenge reduziert wird.

Hinweis

In der folgenden Diskussion ist es wichtig, das Konzept der Filterselektorivität zu berücksichtigen. Selektivität ist der Prozentsatz der Datensätze, die beim Filtern nach einem Prädikat herausgefiltert werden. Ein hochselektives Prädikat bedeutet, dass nach dem Anwenden des Prädikats nur eine Handvoll Datensätze verbleiben, wodurch die Menge an Daten reduziert wird, die dann effektiv verarbeitet werden müssen.

In der Reihenfolge der Wichtigkeit:

  • Verweisen nur auf Tabellen, deren Daten von der Abfrage benötigt werden. Wenn Sie beispielsweise den union Operator mit Tabellenverweise mit Einem Feldhalter verwenden, ist es von einem Leistungspunkt aus besser, nur auf eine Handvoll Tabellen zu verweisen, anstatt einen Feldhalter (*) zu verwenden, um auf alle Tabellen zu verweisen und dann daten mithilfe eines Prädikats für den Namen der Quelltabelle herauszufiltern.

  • Nutzen Sie den Datenbereich einer Tabelle, wenn die Abfrage nur für einen bestimmten Bereich relevant ist. Die table()-Funktion bietet eine effiziente Möglichkeit, Daten zu entfernen, indem sie sie gemäß der Zwischenspeicherungsrichtlinie (dem DataScope-Parameter ) eingrenzen.

  • Wenden Sie den where Abfrageoperator unmittelbar nach Tabellenverweise an.

  • Bei Verwendung des where Abfrageoperators kann eine vernünftige Verwendung der Reihenfolge der Prädikate (in einem einzelnen Operator oder mit einer Reihe von aufeinanderfolgenden Operatoren, egal welche) einen erheblichen Einfluss auf die Abfrageleistung haben, wie unten erläutert.

  • Wenden Sie zuerst ganze Shard-Prädikate an. Dies bedeutet, dass Prädikate, die die funktion extent_id() verwenden, zuerst angewendet werden sollten, sowie Prädikate, die die extent_tags()-Funktion verwenden, und Prädikate, die sehr selektiv über die Datenpartitionen der Tabelle (sofern definiert) sind.

  • Wenden Sie dann Prädikate an, die auf datetime Tabellenspalten wirken. Kusto enthält einen sehr effizienten Index für solche Spalten, wodurch häufig ganze Datenshards vollständig eliminiert werden, ohne auf diese Shards zugreifen zu müssen.

  • Wenden Sie dann Prädikate an, die auf string und dynamic Spalten wirken, insbesondere solche Prädikate, die auf Begriffsebene gelten. Die Prädikate sollten nach der Selektivität sortiert werden (z. B. ist die Suche nach einer Benutzer-ID bei Millionen von Benutzern sehr selektiv und in der Regel eine Begriffssuche, für die der Index sehr effizient ist.)

  • Wenden Sie dann Prädikate an, die selektiv sind und auf numerischen Spalten basieren.

  • Für Abfragen, die die Daten einer Tabellenspalte scannen (z. B. für Prädikate wie "enthält "@!@!"), die keine Begriffe enthalten und von der Indizierung nicht profitieren, ordnen Sie die Prädikate so an, dass diejenigen, die Spalten mit weniger Daten scannen, zuerst sind. Dies reduziert die Notwendigkeit, große Spalten zu dekomprimieren und zu scannen.

Vermeiden der Verwendung redundanter qualifizierter Verweise

Entitäten wie Tabellen und materialisierte Ansichten werden anhand des Namens referenziert. Auf die Tabelle kann beispielsweise einfach T (der nicht qualifizierte Name) oder mithilfe eines Datenbankqualifizierers (z. B. database("DB").T wenn sich die Tabelle in einer Datenbank namens befindetDB) oder mithilfe eines vollqualifizierten Namens (z. B. ) auf die Tabelle T verwiesen werden. cluster("X.Y.kusto.windows.net").database("DB").T

Es empfiehlt sich, die Verwendung von Namensqualifikationen zu vermeiden, wenn sie redundant sind, aus den folgenden Gründen:

  1. Nicht qualifizierte Namen sind (für einen menschlichen Leser) leichter zu identifizieren, da sie zur Datenbank im Bereich gehören.

  2. Das Verweisen auf Datenbank-im-Bereich-Entitäten ist immer mindestens genauso schnell und in einigen Fällen viel schneller, als Entitäten, die zu anderen Datenbanken gehören (insbesondere, wenn sich diese Datenbanken in einem anderen Cluster befinden).) Das Vermeiden qualifizierter Namen hilft dem Leser, das Richtige zu tun.

Hinweis

Dies soll nicht heißen, dass qualifizierte Namen schlecht für die Leistung sind. Tatsächlich ist Kusto in den meisten Fällen in der Lage zu identifizieren, wenn ein vollqualifizierter Name auf eine Entität verweist, die zur Datenbank im Bereich gehört, und die Abfrage "kurzschließen", sodass sie nicht als clusterübergreifende Abfrage betrachtet wird. Es wird jedoch empfohlen, sich aus den oben genannten Gründen nicht darauf zu verlassen, wenn dies nicht erforderlich ist.