Bewährte Methoden für Kusto-Abfragesprache Abfragen
Gilt für: ✅Microsoft Fabric✅Azure Data Explorer✅Azure Monitor✅Microsoft Sentinel
Es stehen einige bewährte Methoden zur Verfügung, damit die Abfrage schneller ausgeführt wird.
Kurz gesagt
Aktion | Zweck | Nicht verwenden | Hinweise |
---|---|---|---|
Verringern der Datenmenge, die abgefragt wird | Verwenden Sie Mechanismen wie den where Operator, um die Menge der verarbeiteten Daten zu reduzieren. |
Weitere Informationen zu effizienten Möglichkeiten zur Reduzierung der Datenmenge, die verarbeitet wird, finden Sie unter "Verringern der Menge der verarbeiteten Daten". | |
Vermeiden Sie redundante qualifizierte Verweise | Verwenden Sie beim Verweisen auf lokale Entitäten den nicht qualifizierten Namen. | Weitere Informationen finden Sie unter Vermeiden der Verwendung redundanter qualifizierter Verweise. | |
datetime Spalten |
Verwenden Sie den Datentyp datetime . |
Verwenden Sie nicht den long Datentyp. |
Verwenden Sie in Abfragen keine Unix-Zeitkonvertierungsfunktionen, z unixtime_milliseconds_todatetime() . B. . Verwenden Sie stattdessen Updaterichtlinien, um Unix-Zeit während der Aufnahme in den datetime Datentyp zu konvertieren. |
Zeichenfolgenoperatoren | Mithilfe des Operators has |
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 == . |
Nicht =~ verwenden. |
Verwenden Sie nach Möglichkeit Operatoren, die zwischen Groß- und Kleinschreibung unterscheiden. |
Verwenden Sie in . |
Nicht in~ verwenden. |
||
Verwenden Sie contains_cs . |
Nicht contains verwenden. |
Die Verwendung has /has_cs wird bevorzugt für .contains /contains_cs |
|
Durchsuchen von Text | Suchen Sie in einer bestimmten Spalte. | Nicht * verwenden. |
* 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. | Mit dieser Methode zahlen Sie nur einmal für die Spaltenextraktion. | |
Lookup für seltene Schlüssel/Werte in dynamischen Objekten | Verwenden Sie MyTable | where DynamicColumn has "Rare value" | where DynamicColumn.SomeKey == "Rare value" . |
Nicht MyTable | where DynamicColumn.SomeKey == "Rare value" verwenden. |
Mit dieser Methode filtern Sie die meisten Datensätze heraus und führen nur JSON-Analysen für den Rest durch. |
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 Typkonvertierungen auf mehr als eine 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 ungebundener Abfragen über unbekannte Datasets kann zu einer Rückgabe von Gigabyte an Ergebnissen führen, was zu einer langsamen Antwort und einer ausgelasteten Umgebung führt. | |
Vergleiche ohne Unterscheidung von Groß-/Kleinschreibung | Verwenden Sie Col =~ "lowercasestring" . |
Nicht tolower(Col) == "lowercasestring" verwenden. |
|
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) . |
||
Zusammenfassungsoperator | Verwenden Sie "hint.shufflekey=<key>", wenn der group by keys summarize Operator eine hohe Kardinalität hat. |
Hohe Kardinalität ist idealerweise mehr als eine Million. | |
Verknüpfungsoperator | Wählen Sie die Tabelle mit den wenigsten Zeilen als erste (ganz links in der Abfrage) aus. | ||
Verwenden Sie in anstelle des linken Semis join zum Filtern nach einer einzelnen Spalte. |
|||
Verknüpfung über Cluster hinweg | Führen Sie die Abfrage auf der rechten Seite der Verknüpfung über Remoteumgebungen aus, z. B. Cluster oder Eventhouses, in denen sich die meisten Daten befinden. | ||
Verknüpfung, wenn die linke Seite klein und rechts ist groß | Verwenden Sie "hint.strategy=broadcast". | Klein bezieht sich auf bis zu 100 Mb (MB) von Daten. | |
Verknüpfung, wenn die rechte Seite klein und links ist groß | 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. | |
Verknüpfung, wenn beide Seiten zu groß sind | Verwenden Sie "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 Analyseoperator. | Verwenden Sie nicht mehrere extract() -Anweisungen. |
Beispiel: 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 dennoch die Semantik der Abfrage beibehalten. | Beispielsweise Filter oder projekteigene erforderliche Spalten. Weitere Informationen finden Sie unter Optimieren von Abfragen, die benannte Ausdrücke verwenden. | |
Materialisierte Ansichten verwenden | Verwenden Sie materialisierte Ansichten zum Speichern häufig verwendeter Aggregationen. Verwenden Sie die materialized_view() Funktion, um nur materialisierte Teile abzufragen. |
materialized_view('MV') |
Verringern der Datenmenge, die verarbeitet wird
Die Leistung einer Abfrage hängt direkt von der Datenmenge ab, die verarbeitet werden muss. Je weniger Daten verarbeitet werden, desto schneller wird die Abfrage ausgeführt (und desto weniger Ressourcen werden verbraucht). Daher besteht die wichtigste bewährte Methode darin, die Abfrage so zu strukturieren, dass die Menge der verarbeiteten Daten reduziert wird.
Hinweis
In der folgenden Diskussion ist es wichtig, das Konzept der Filterauswahl zu berücksichtigen. Selektorivität ist der Prozentsatz der Datensätze, die beim Filtern nach einem Prädikat gefiltert werden. Ein hoch selektives Prädikat bedeutet, dass nur eine Handvoll Datensätze nach dem Anwenden des Prädikats verbleiben, wodurch die Menge der Daten reduziert wird, die dann effektiv verarbeitet werden müssen.
In Reihenfolge der Wichtigkeit:
Nur Referenztabellen, deren Daten von der Abfrage benötigt werden. Wenn Sie z. B. den
union
Operator mit Wildcardtabellenverweisen verwenden, ist es besser, aus Leistungsgründen nur auf eine Handvoll Tabellen zu verweisen, anstatt einen Wildcard (*
) zu verwenden, um auf alle Tabellen zu verweisen und dann Daten mithilfe eines Prädikats für den Quelltabellennamen 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 beseitigen, indem sie gemäß der Zwischenspeicherungsrichtlinie (dem DataScope-Parameter ) definiert wird.
Wenden Sie den
where
Abfrageoperator unmittelbar auf Tabellenverweise an.Bei Verwendung des
where
Abfrageoperators kann die Reihenfolge, in der Sie die Prädikate platzieren, unabhängig davon, ob Sie einen einzelnenwhere
Operator oder mehrere aufeinander folgendewhere
Operatoren verwenden, erhebliche Auswirkungen auf die Abfrageleistung haben.Wenden Sie zuerst Ganzhard-Prädikate an. Dies bedeutet, dass Prädikate, die die Funktion extent_id() und extent_tags() verwenden, zuerst angewendet werden sollten. Wenn Sie auch selektive Prädikate haben, die die Daten auf bestimmte Partitionen eingrenzen, sollten sie zuerst angewendet werden.
Wenden Sie dann Prädikate an, die auf
datetime
Tabellenspalten reagieren. Kusto enthält einen effizienten Index für solche Spalten, häufig werden ganze Datenshards vollständig eliminiert, ohne auf diese Shards zugreifen zu müssen.Wenden Sie dann Prädikate an, die auf
string
unddynamic
Spalten reagieren, insbesondere solche Prädikate, die auf Begriffsebene angewendet werden. Ordnen Sie die Prädikate nach der Selektorivität an. Beispielsweise ist die Suche nach einer Benutzer-ID, wenn Millionen von Benutzern vorhanden sind, sehr selektiv und umfasst 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.
Bei Abfragen, die die Daten einer Tabellenspalte durchsuchen (z. B. für Prädikate wie
contains
"@!@!"
z. B., die keine Begriffe haben und nicht von der Indizierung profitieren), ordnen Sie die Prädikate so an, dass die Daten, die Spalten mit weniger Daten scannen, zuerst sortiert werden. Dadurch wird die Notwendigkeit reduziert, große Spalten zu dekomprimieren und zu scannen.
Vermeiden Sie redundante qualifizierte Verweise
Verweisen Sie auf Entitäten wie Tabellen und materialisierte Ansichten anhand des Namens.
Auf die Tabelle T
kann z. B. einfach T
(nicht qualifizierter Name) oder mithilfe eines Datenbankqualifizierers (z database("DB").T
. B. wenn sich die Tabelle in einer Datenbank befindet DB
), oder mithilfe eines vollqualifizierten Namens (z cluster("<serviceURL>").database("DB").T
. B. ) auf die Tabelle verwiesen werden.
Auf die Tabelle T
kann z. B. einfach T
(nicht qualifizierter Name) oder mithilfe eines Datenbankqualifizierers (z database("DB").T
. B. wenn sich die Tabelle in einer Datenbank befindet DB
), oder mithilfe eines vollqualifizierten Namens (z cluster("X.Y.kusto.windows.net").database("DB").T
. B. ) auf die Tabelle verwiesen werden.
Es ist eine bewährte Methode, namensqualifikationen zu vermeiden, wenn sie redundant sind, aus den folgenden Gründen:
Nicht qualifizierte Namen sind einfacher zu identifizieren (für einen menschlichen Leser), die zum Datenbankbereich gehören.
Das Verweisen auf Datenbank-in-Bereich-Entitäten ist immer mindestens so schnell, und in einigen Fällen viel schneller, dann Entitäten, die zu anderen Datenbanken gehören.
Dies gilt insbesondere, wenn sich diese Datenbanken in einem anderen Cluster befinden.
Dies gilt insbesondere, wenn sich diese Datenbanken in einem anderen Eventhouse befinden.
Das Vermeiden qualifizierter Namen hilft dem Leser, das richtige Zu tun.
Hinweis
Dies bedeutet nicht, dass qualifizierte Namen für die Leistung schlecht sind. Tatsächlich ist Kusto in den meisten Fällen in der Lage zu identifizieren, wann ein vollqualifizierter Name auf eine Entität verweist, die zur Datenbank im Bereich gehört, und die Abfrage "kurzschluss", sodass sie nicht als clusterübergreifende Abfrage angesehen wird. Es wird jedoch nicht empfohlen, bei Bedarf darauf zu vertrauen.
Hinweis
Dies bedeutet nicht, dass qualifizierte Namen für die Leistung schlecht 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 zum Datenbankbereich gehört. Es wird jedoch nicht empfohlen, bei Bedarf darauf zu vertrauen.