Kusto 查詢語言 查詢的最佳做法

以下有數個可供遵循的最佳做法,讓您更快速執行查詢。

簡短來說

動作 使用 請勿使用 注意
減少正在查詢的數據量 使用運算子之類的 where 機制來減少正在處理的數據量。 如需減少正在處理之數據量的有效率方式,請參閱下方。
避免使用備援限定參考 參考本機實體時,請使用不合格的名稱。 如需主題的詳細資訊,請參閱下文。
datetime 使用 datetime 數據類型。 請勿使用 long 數據類型。 在查詢中,請勿使用 unix 時間轉換函式,例如 unixtime_milliseconds_todatetime()。 請改用更新原則,在擷取期間將 unix 時間 datetime 轉換成數據類型。
字串運算子 使用 has 運算子 請勿使用 contains 尋找完整權杖時,has 的效果更好,因為其不會尋找子字串。
區分大小寫的運算子 使用== 請勿使用 =~ 可能的話,請使用區分大小寫的運算子。
使用in 請勿使用 in~
使用contains_cs 請勿使用 contains 如果您可使用 has/has_cs,而不使用 contains/contains_cs,甚至更好。
搜尋文字 查看特定資料行 請勿使用 * * 會在所有資料行中進行全文檢索搜尋。
從跨數百萬個資料列的 dynamic 物件中擷取欄位 如果大部分查詢都會從跨數百萬個資料列的 dynamic 物件中擷取欄位,請在擷取時將您的資料行具體化。 如此一來,您只需針對資料行擷取付費一次。
動態物件中查詢少用的索引鍵/值 使用MyTable | where DynamicColumn has "Rare value" | where DynamicColumn.SomeKey == "Rare value" 請勿使用 MyTable | where DynamicColumn.SomeKey == "Rare value" 如此一來,您就可以篩選出大部分的記錄,並僅針對其餘項目執行 JSON 剖析。
陳述式,其中包含您多次使用的值 使用 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 運算子 當 summarize 運算子的 具有高基數時group by keys,請使用 hint.shufflekey=<key> 高基數理想上高於 1 百萬。
join 運算子 選取具有較少資料列的資料表作為第一個資料表 (查詢最左邊)。
使用 in 而非左半分 join 篩選單一數據行。
跨叢集聯結 跨叢集,在聯結的「右」側執行查詢,大部分的資料都位於聯結中。
當左側較小而右側較大時聯結 使用 hint.strategy=broadcast 小型是指最多 100 MB 的數據。
當右側很小且左側很大時聯結 使用 查閱運算符join 而不是運算符 如果查閱右側大於數十個 MB,查詢將會失敗。
當兩邊都太大時聯結 使用 hint.shufflekey=<key> 當聯結索引鍵具有高基數時使用。
在有字串共用相同格式或模式的資料行上擷取值 使用 parse 運算子 請勿使用數個 extract() 陳述式。 例如,"Time = <time>, ResourceId = <resourceId>, Duration = <duration>, ...." 之類的值
extract() 函式 當剖析的字串並未全部遵循相同的格式或模式時使用。 使用 REGEX 來擷取必要的值。
materialize() 函式 推送可減少具體化數據集的所有可能運算元,但仍保留查詢的語意。 例如,使用篩選條件,或僅投射必要的資料行。 如需詳細資訊,請參閱 優化使用具名表達式的查詢
使用具體化檢視 使用具體化視圖來儲存常用的彙總。 建議使用 materialized_view() 函式以僅查詢具體化部分 materialized_view('MV')

減少正在處理的數據量

查詢的效能會直接取決於它需要處理的數據量。 處理的數據越少,查詢 (越快,耗用的資源就越少) 。 因此,最重要的最佳做法是以減少所處理數據量的方式來建構查詢。

注意

在下列討論中,請務必記住 篩選選擇性的概念。 選取性是依某些述詞篩選時,會篩選掉記錄的百分比。 高度選擇性述詞表示在套用述詞之後,只有少數記錄會保留下來,以減少需要有效地處理的數據量。

重要性順序:

  • 只參考查詢需要其數據的數據表。 例如,搭配通配符數據表參考使用 union 運算符時,最好從效能點檢視只參考少數數據表,而不是使用通配符 () * 來參考所有數據表,然後使用源數據表名稱上的述詞篩選出數據。

  • 如果查詢只與特定範圍相關,請利用數據表的數據範圍。 table () 函式會根據快取原則 (DataScope 參數) ,提供有效率的方式消除數據。

  • 緊接在數據表參考之後套 where 用查詢運算元。

  • 使用 where 查詢運算符時,在單一運算符中 (述詞順序的謹慎使用,或是具有一些連續運算符,這並不重要,) 對查詢效能有顯著的影響,如下所述。

  • 先套用整個分區述詞。 這表示應該先套用使用 extent_id () 函式的述詞,如同使用 extent_tags () 函數的述詞,以及在定義) 時,非常選擇性地使用數據表數據分割的述詞 (。

  • 然後套用對數據表數據行採取動作的 datetime 述詞。 Kusto 在這類數據行上包含非常有效率的索引,通常完全消除整個數據分區,而不需要存取這些分區。

  • 然後套用處理 stringdynamic 數據行的述詞,特別是適用於詞彙層級的述詞。 述詞應該依選擇性 (排序,例如,當有數百萬個使用者非常選擇性時搜尋使用者標識碼,而且通常是索引非常有效率的字詞搜尋。)

  • 然後套用選擇性述詞,並以數值數據行為基礎。

  • 最後,針對掃描數據表數據行數據 (的查詢,例如 'contains “@!@!” 等述詞沒有詞彙,而且無法受益於索引編製) ,則排序述詞,以便先掃描數據行的數據行。 這可減少解壓縮和掃描大型數據行的需求。

避免使用備援限定參考

數據表和具體化檢視等實體會依名稱參考。 例如, T 您可以直接 T (未限定 的名稱) ,或使用資料庫限定符 (,例如 database("DB").T 當數據表位於稱為 DB) 的資料庫中,或使用完整名稱 (例如 cluster("X.Y.kusto.windows.net").database("DB").T) 。

基於下列原因,最好避免在名稱限定性為備援時使用名稱限定性:

  1. 不合格的名稱更容易識別人類讀取者) 屬於資料庫範圍內的 (。

  2. 參考範圍中的資料庫實體一律速度至少一樣快,在某些情況下,屬於其他資料庫的實體 (特別是當這些資料庫位於不同的叢集中時。) 避免限定名稱有助於讀取者執行正確的事。

注意

這不表示限定名稱對效能而言不正確。 事實上,Kusto 在大部分情況下都可以識別完整名稱何時參考屬於資料庫內範圍的實體,並「縮短」查詢,使其不會被視為跨叢集查詢。 不過,基於上述指定的原因,建議您不要視需要依賴此功能。