Procedure consigliate per Linguaggio di query Kusto query
Si applica a: ✅Microsoft Fabric✅Azure Esplora dati✅ Azure Monitor✅Microsoft Sentinel
Di seguito sono descritte alcune procedure consigliate da seguire per velocizzare l'esecuzione delle query.
Insomma
Azione | Utilizzo | Non usare | Note |
---|---|---|---|
Ridurre la quantità di dati sottoposti a query | Usare meccanismi come l'operatore where per ridurre la quantità di dati elaborati. |
Per altre informazioni su modi efficienti per ridurre la quantità di dati elaborati, vedere Ridurre la quantità di dati elaborati. | |
Evitare di usare riferimenti qualificati ridondanti | Quando si fa riferimento a entità locali, usare il nome non qualificato. | Per altre informazioni, vedere Evitare di usare riferimenti qualificati ridondanti. | |
datetime Colonne |
Usare il datetime tipo di dati. |
Non usare il long tipo di dati. |
Nelle query non usare funzioni di conversione del tempo Unix, ad esempio unixtime_milliseconds_todatetime() . Usare invece i criteri di aggiornamento per convertire l'ora Unix nel tipo di dati durante l'inserimento datetime . |
Operatori stringa | Usando l'operatore has . |
Non usare contains |
Per la ricerca di token completi has funziona meglio, perché non cerca le sottostringhe. |
Operatori con distinzione tra maiuscole e minuscole | Usare == . |
Non utilizzare =~ . |
Usare gli operatori con distinzione tra maiuscole e minuscole quando possibile. |
Usare in . |
Non utilizzare in~ . |
||
Usare contains_cs . |
Non utilizzare contains . |
L'uso di è preferibile acontains_cs contains / .has /has_cs |
|
Ricerca di testo | Esaminare una colonna specifica. | Non utilizzare * . |
* esegue una ricerca full-text in tutte le colonne. |
Estrarre campi da oggetti dinamici su milioni di righe | Materializzare la colonna in fase di inserimento se la maggior parte delle query estrae campi da oggetti dinamici su milioni di righe. | Con questo metodo si paga una sola volta per l'estrazione di colonne. | |
Ricerca di chiavi/valori rari negli oggetti dinamici | Usare MyTable | where DynamicColumn has "Rare value" | where DynamicColumn.SomeKey == "Rare value" . |
Non utilizzare MyTable | where DynamicColumn.SomeKey == "Rare value" . |
Con questo metodo si filtra la maggior parte dei record e si esegue solo l'analisi JSON nel resto. |
Istruzione let con un valore che viene usato più volte |
Usare la funzione materialize(). | Per altre informazioni su come usare materialize() , vedere materialize(). Per altre informazioni, vedere Ottimizzare le query che usano espressioni denominate. |
|
Applicare conversioni di tipi su più di un miliardo di record | Rimodellare la query per ridurre la quantità di dati inseriti nella conversione. | Se possibile, evitare di convertire grandi quantità di dati. | |
Nuove query | Usare limit [small number] o count alla fine. |
L'esecuzione di query non associate su set di dati sconosciuti può restituire gigabyte di risultati, causando una risposta lenta e un ambiente occupato. | |
Confronti senza distinzione tra maiuscole e minuscole | Usare Col =~ "lowercasestring" . |
Non utilizzare tolower(Col) == "lowercasestring" . |
|
Confrontare dati già in lettere minuscole (o maiuscole) | Col == "lowercasestring" (o Col == "UPPERCASESTRING" ). |
Evitare di usare confronti che non fanno distinzione tra maiuscole e minuscole. | |
Applicazione di filtri alle colonne | Applicare un filtro su una colonna della tabella. | Non applicare filtri su una colonna calcolata. | |
Utilizzare T | where predicate(*Expression*) . |
Non usare T | extend _value = *Expression* | where predicate(_value) |
||
Operatore summarize | Usare hint.shufflekey =<key> quando l'oggetto group by keys dell'operatore summarize ha una cardinalità elevata. |
La cardinalità elevata è idealmente più di un milione. | |
Operatore join | Selezionare la tabella con il minor numero di righe come prima (più a sinistra nella query). | ||
Usare in invece di sinistra semi join per filtrare in base a una singola colonna. |
|||
Creare un join tra cluster | Eseguire la query sul lato "destro" del join in ambienti remoti, ad esempio cluster o case eventi, in cui si trova la maggior parte dei dati. | ||
Join quando il lato sinistro è piccolo e destro è grande | Usare hint.strategy=broadcast. | Small fa riferimento a un massimo di 100 megabyte (MB) di dati. | |
Join quando il lato destro è piccolo e sinistro è grande | Usare l'operatore lookup anziché l'operatore join |
Se il lato destro della ricerca è maggiore di diverse decine di MB, la query ha esito negativo. | |
Join quando entrambi i lati sono troppo grandi | Usare hint.shufflekey=<key>. | Usare quando la chiave di join ha una cardinalità elevata. | |
Estrarre valori in una colonna con stringhe che condividono lo stesso formato o modello | Usare l'operatore parse. | Non usare più istruzioni extract() . |
Ad esempio, valori come "Time = <time>, ResourceId = <resourceId>, Duration = <duration>, ...." . |
Funzione extract() | Usare quando le stringhe analizzate non hanno tutte lo stesso formato o modello. | Estrarre i valori necessari tramite REGEX. | |
Funzione materialize() | Eseguire il push di tutti i possibili operatori che riducono il set di dati materializzato e mantengono comunque la semantica della query. | Ad esempio, applicare filtri o proiettare solo le colonne necessarie. Per altre informazioni, vedere Ottimizzare le query che usano espressioni denominate. | |
Usare viste materializzate | Usare viste materializzate per archiviare le aggregazioni di uso comune. Preferisce usare la materialized_view() funzione solo per eseguire query su parte materializzata. |
materialized_view('MV') |
Ridurre la quantità di dati elaborati
Le prestazioni di una query dipendono direttamente dalla quantità di dati da elaborare. Minore è il numero di dati elaborati, più veloce è la query e il minor numero di risorse utilizzate. Pertanto, la procedura consigliata più importante consiste nel strutturare la query in modo da ridurre la quantità di dati elaborati.
Nota
Nella discussione seguente è importante tenere presente il concetto di selettività dei filtri. La selettività è la percentuale dei record che vengono filtrati quando si filtra in base a un predicato. Un predicato altamente selettivo significa che solo pochi record rimangono dopo l'applicazione del predicato, riducendo la quantità di dati che devono essere elaborati in modo efficace.
In ordine di importanza:
Fare riferimento solo a tabelle i cui dati sono necessari per la query. Ad esempio, quando si usa l'operatore
union
con riferimenti di tabella con caratteri jolly, è preferibile passare da un punto di vista delle prestazioni per fare riferimento solo a una manciata di tabelle, anziché usare un carattere jolly (*
) per fare riferimento a tutte le tabelle e quindi filtrare i dati usando un predicato sul nome della tabella di origine.Sfruttare l'ambito dei dati di una tabella se la query è rilevante solo per un ambito specifico. La funzione table() offre un modo efficiente per eliminare i dati tramite l'ambito in base ai criteri di memorizzazione nella cache (il parametro DataScope ).
Applicare l'operatore
where
query immediatamente dopo i riferimenti alla tabella.Quando si usa l'operatore query, l'ordine
where
in cui si inserisce i predicati, indipendentemente dal fatto che si usi un singolowhere
operatore o più operatori consecutiviwhere
, può avere un effetto significativo sulle prestazioni della query.Applicare prima predicati interi partizioni. Ciò significa che i predicati che usano la funzione extent_id() e extent_tags() devono essere applicati per primi. Inoltre, quando si dispone di predicati selettivi che restringeno i dati a partizioni specifiche, devono essere applicati per primi.
Applicare quindi predicati che agiscono sulle colonne della
datetime
tabella. Kusto include un indice efficiente su tali colonne, spesso eliminando completamente intere partizioni di dati senza dover accedere a tali partizioni.Applicare quindi predicati che agiscono su
string
edynamic
colonne, soprattutto questi predicati che si applicano a livello di termine. Ordinare i predicati in base alla selettività. Ad esempio, la ricerca di un ID utente quando sono presenti milioni di utenti è altamente selettiva e in genere comporta una ricerca di termini, per cui l'indice è molto efficiente.Applicare quindi predicati selettivi e basati su colonne numeriche.
Infine, per le query che analizzano i dati di una colonna di tabella (ad esempio, per predicati come
contains
"@!@!"
, che non hanno termini e non traggono vantaggio dall'indicizzazione), ordinare i predicati in modo che quelli che analizzano le colonne con meno dati siano prima. In questo modo si riduce la necessità di decomprimere e analizzare colonne di grandi dimensioni.
Evitare di usare riferimenti qualificati ridondanti
Fare riferimento a entità come tabelle e viste materializzate in base al nome.
Ad esempio, è possibile fare riferimento alla tabella come semplicemente T
(nome non qualificato) o usando un qualificatore di database (ad esempio, database("DB").T
quando la tabella T
si trova in un database denominato DB
) o usando un nome completo (ad esempio, cluster("<serviceURL>").database("DB").T
).
Ad esempio, è possibile fare riferimento alla tabella come semplicemente T
(nome non qualificato) o usando un qualificatore di database (ad esempio, database("DB").T
quando la tabella T
si trova in un database denominato DB
) o usando un nome completo (ad esempio, cluster("X.Y.kusto.windows.net").database("DB").T
).
È consigliabile evitare di usare le qualifiche dei nomi quando sono ridondanti, per i motivi seguenti:
I nomi non qualificati sono più facili da identificare (per un lettore umano) come appartenenti all'ambito del database.
Fare riferimento alle entità con ambito di database è sempre altrettanto veloce e in alcuni casi molto più veloce, quindi le entità che appartengono ad altri database.
Ciò vale soprattutto quando tali database si trovano in un cluster diverso.
Ciò vale soprattutto quando tali database si trovano in un'altra eventhouse.
Evitare nomi qualificati aiuta il lettore a fare la cosa giusta.
Nota
Ciò non significa che i nomi qualificati siano negativi per le prestazioni. Kusto, infatti, è in grado nella maggior parte dei casi di identificare quando un nome completo fa riferimento a un'entità appartenente all'ambito del database e al "corto circuito" della query in modo che non venga considerata una query tra cluster. Tuttavia, non è consigliabile basarsi su questo se non necessario.
Nota
Ciò non significa che i nomi qualificati siano negativi per le prestazioni. Kusto, infatti, è in grado nella maggior parte dei casi di identificare quando un nome completo fa riferimento a un'entità appartenente all'ambito del database. Tuttavia, non è consigliabile basarsi su questo se non necessario.