Kusto 查詢語言 查詢的最佳做法
適用於:✅Microsoft網狀架構✅Azure 數據✅總管 Azure 監視器✅Microsoft Sentinel
以下是幾個要遵循的最佳做法,讓您的查詢執行速度更快。
總之
動作 | 使用 | 請勿使用 | 備註 |
---|---|---|---|
減少查詢的數據量 | 使用運算子之類的 where 機制來減少所處理的數據量。 |
如需降低所處理數據量之有效方式的詳細資訊,請參閱 減少正在處理的數據量。 | |
避免使用備援限定參考 | 參考本機實體時,請使用未限定的名稱。 | 如需詳細資訊,請參閱 避免使用備援限定參考。 | |
datetime 列 |
datetime 使用數據類型。 |
請勿使用 long 數據類型。 |
在查詢中,請勿使用 Unix 時間轉換函式,例如 unixtime_milliseconds_todatetime() 。 請改用更新原則,在擷取期間,使用更新原則將 Unix 時間轉換成 datetime 數據類型。 |
字串運算子 | 使用 has 運算子。 |
請勿使用 contains |
尋找完整令牌時, has 效果更好,因為它不會尋找子字串。 |
區分大小寫的運算子 | 使用 == 。 |
請勿使用 =~ 。 |
盡可能使用區分大小寫的運算符。 |
使用 in 。 |
請勿使用 in~ 。 |
||
使用 contains_cs 。 |
請勿使用 contains 。 |
使用 has /has_cs 是慣用的 contains /contains_cs 。 |
|
搜尋文字 | 查看特定數據行。 | 請勿使用 * 。 |
* 會跨所有數據行執行全文搜索。 |
從 數百萬個數據列的動態物件 擷取字段 | 如果您的大部分查詢從數百萬個數據列的動態物件擷取欄位,請在擷取時間具體化數據行。 | 使用此方法時,您只需要支付一次數據行擷取費用。 | |
查閱動態物件中的 罕見索引鍵/值 | 使用 MyTable | where DynamicColumn has "Rare value" | where DynamicColumn.SomeKey == "Rare value" 。 |
請勿使用 MyTable | where DynamicColumn.SomeKey == "Rare value" 。 |
使用此方法時,您會篩選掉大部分的記錄,而且只會對其餘部分執行 JSON 剖析。 |
let 語句,其中包含您多次使用的值 |
使用materialize() 函式。 | 如需如何使用 materialize() 的詳細資訊,請參閱 materialize()。 如需詳細資訊,請參閱 優化使用具名表達式的查詢。 |
|
在超過10億筆記錄上套用類型轉換 | 重新調整查詢,以減少送入轉換的數據量。 | 如果可以避免,請勿轉換大量數據。 | |
新查詢 | 使用 limit [small number] 或 count 結尾。 |
在未知數據集上執行未系結的查詢,可能會傳回 GB 的結果,進而產生緩慢的回應和忙碌的環境。 | |
不區分大小寫的比較 | 使用 Col =~ "lowercasestring" 。 |
請勿使用 tolower(Col) == "lowercasestring" 。 |
|
比較已經在小寫的數據(或大寫) | Col == "lowercasestring" (或 Col == "UPPERCASESTRING" )。 |
避免使用不區分大小寫的比較。 | |
篩選數據行 | 篩選數據表數據行。 | 請勿篩選計算結果列。 | |
使用 T | where predicate(*Expression*) |
請勿使用 T | extend _value = *Expression* | where predicate(_value) |
||
summarize 運算符 | 當 運算子具有高基數時group by keys summarize ,請使用hint.shufflekey=<key>。 |
高基數在理想情況下超過100萬。 | |
join 運算子 | 選取包含最少數據列的數據表作為第一個數據表(查詢中最左邊)。 | ||
使用 in 而非左半 join 部分來篩選單一數據行。 |
|||
跨叢集聯結 | 在聯結的「右側」端執行查詢,例如叢集或 Eventhouses,其中大部分的數據都位於其中。 | ||
當左側很小且右側很大時聯結 | 使用 hint.strategy=broadcast。 | 小型是指最多 100 MB 的數據。 | |
當右側很小且左側很大時聯結 | 使用查閱運算子,join 而不是運算符 |
如果查閱的右側大於數十 MB,則查詢會失敗。 | |
當雙方太大時聯結 | 使用 hint.shufflekey=<key>。 | 當聯結索引鍵具有高基數時,請使用 。 | |
擷取具有共用相同格式或模式之字串的數據行值 | 使用剖 析運算符。 | 請勿使用數個 extract() 語句。 |
例如,之類的 "Time = <time>, ResourceId = <resourceId>, Duration = <duration>, ...." 值。 |
extract() 函式 | 剖析的字串不全都遵循相同的格式或模式時使用。 | 使用 REGEX 擷取所需的值。 | |
materialize() 函式 | 推送所有可能運算符,以減少具體化數據集,但仍保留查詢的語意。 | 例如,篩選或僅專案所需的數據行。 如需詳細資訊,請參閱 優化使用具名表達式的查詢。 | |
使用具體化檢視 | 使用 具體化檢視 來儲存常用的匯總。 偏好使用函 materialized_view() 式只查詢具體化部分。 |
materialized_view('MV') |
減少正在處理的數據量
查詢的效能會直接取決於它需要處理的數據量。 處理的資料越少,查詢越快 (耗用的資源越少)。 因此,最重要的最佳做法是以降低所處理數據量的方式建構查詢。
注意
在下列討論中,請務必記住篩選選擇性的概念。 選取性是依某些述詞篩選時,記錄的百分比會篩選掉。 高度選擇性的述詞表示在套用述詞之後,只有少數記錄會保留下來,減少需要有效處理的數據量。
重要性順序:
只有參考查詢需要其數據的數據表。 例如,搭配通配符數據表參考使用
union
運算符時,最好從效能點到只參考少數數據表,而不是使用通配符 (*
) 來參考所有數據表,然後使用源數據表名稱上的述詞篩選出數據。如果查詢只與特定範圍相關,請利用數據表的數據範圍。 table() 函式會根據快取原則(DataScope 參數)來提供有效的方式來消除數據。
緊接在數據表參考之後套
where
用查詢運算元。使用
where
查詢運算符時,不論您使用單where
一運算符或多個連續where
運算符,放置述詞的順序,都可能會對查詢效能產生顯著的影響。請先套用整個分區述詞。 這表示應先套用使用 extent_id() 函 式和 extent_tags() 函 式的述詞。 此外,當您有選擇性述詞將數據縮小至特定分割區時,應該先套用它們。
然後套用在數據表數據行上
datetime
動作的述詞。 Kusto 包含這類數據行的有效索引,通常會完全排除整個數據分區,而不需要存取這些分區。然後套用在 和
dynamic
數據行上string
執行的述詞,特別是適用於詞彙層級的述詞。 依選擇性排序述詞。 例如,當有數百萬個使用者高度選擇性且通常涉及字詞搜尋時,搜尋使用者標識碼會非常有效率。然後套用選擇性的述詞,並以數值數據行為基礎。
最後,對於掃描數據表數據行數據的查詢(例如,對於
contains
"@!@!"
沒有字詞且無法受益於編製索引的述詞),請排序述詞,讓掃描數據行的數據行先少。 這樣做可減少解壓縮和掃描大型數據行的需求。
避免使用備援限定參考
依名稱參考數據表和具體化檢視等實體。
例如,數據表 T
可以直接 T
參考為( 未限定 的名稱),或使用資料庫限定符(例如, database("DB").T
當數據表位於名為 DB
的資料庫中時),或是使用完整名稱(例如, cluster("<serviceURL>").database("DB").T
)。
例如,數據表 T
可以直接 T
參考為( 未限定 的名稱),或使用資料庫限定符(例如, database("DB").T
當數據表位於名為 DB
的資料庫中時),或是使用完整名稱(例如, cluster("X.Y.kusto.windows.net").database("DB").T
)。
最佳作法是避免在名稱限定性備援時使用名稱資格,原因如下:
不合格的名稱更容易識別(針對人類讀取者)屬於資料庫範圍內。
參考範圍中的資料庫實體一律會盡可能快,而且在某些情況下,更快速地參考屬於其他資料庫的實體。
當這些資料庫位於不同的叢集中時,尤其如此。
當這些資料庫位於不同的 Eventhouse 時,尤其如此。
避免限定名稱可協助讀取者執行正確的動作。
注意
這並不表示限定名稱對效能不好。 事實上,Kusto 在大部分情況下都能夠識別完整名稱參考屬於資料庫範圍內的實體,並「縮短」查詢,使其不被視為跨叢集查詢。 不過,我們不建議在必要時依賴此功能。
注意
這並不表示限定名稱對效能不好。 事實上,Kusto 在大部分情況下都能夠識別完整名稱參考屬於資料庫範圍內之實體的時機。 不過,我們不建議在必要時依賴此功能。