時段聯結
在一些高基數索引鍵上聯結兩個大型數據集,例如作業標識碼或會話標識碼,並進一步限制需要與左側 ($left) 記錄相符的右側 ($right) 記錄,方法是在左側和右側數據行之間的 datetime
「時間距離」上新增限制。
上述作業與一般的 Kusto 聯結作業不同,因為針對 equi-join
比對左右數據集之間的高基數索引鍵部分,系統也可以套用距離函式,並使用它大幅加快聯結速度。
注意
距離函式的行為和相等不同 (亦即,當 dist(x,y) 和 dist(y,z) 為 true 時,dist(x,z) 不會是 true。) 在內部,我們有時會將此稱為「對角線聯結」。
例如,如果您想要在相對較短的時間範圍內識別事件順序,假設您擁有的資料表 T
具有下列結構描述:
SessionId
:string
類型的資料行,具有串聯識別碼。EventType
:string
類型的資料行,可識別記錄的事件類型。Timestamp
:datetime
類型的資料行,表示記錄描述事件時的時間。
let T = datatable(SessionId:string, EventType:string, Timestamp:datetime)
[
'0', 'A', datetime(2017-10-01 00:00:00),
'0', 'B', datetime(2017-10-01 00:01:00),
'1', 'B', datetime(2017-10-01 00:02:00),
'1', 'A', datetime(2017-10-01 00:03:00),
'3', 'A', datetime(2017-10-01 00:04:00),
'3', 'B', datetime(2017-10-01 00:10:00),
];
T
輸出
SessionId | EventType | 時間戳記 |
---|---|---|
0 | A | 2017-10-01 00:00:00.0000000 |
0 | B | 2017-10-01 00:01:00.0000000 |
1 | B | 2017-10-01 00:02:00.0000000 |
1 | A | 2017-10-01 00:03:00.0000000 |
3 | A | 2017-10-01 00:04:00.0000000 |
3 | B | 2017-10-01 00:10:00.0000000 |
問題陳述
我們的查詢應該會回答下列問題:
找出所有工作階段識別碼,其中 A
事件類型會在 1min
時間範圍內的 B
事件類型之後。
注意
在上述的範例資料中,符合條件的唯一工作階段識別碼是 0
。
在語義上,下列查詢會回答此問題 (雖然沒有效率)。
T
| where EventType == 'A'
| project SessionId, Start=Timestamp
| join kind=inner
(
T
| where EventType == 'B'
| project SessionId, End=Timestamp
) on SessionId
| where (End - Start) between (0min .. 1min)
| project SessionId, Start, End
輸出
SessionId | 開始 | 結束 |
---|---|---|
0 | 2017-10-01 00:00:00.0000000 | 2017-10-01 00:01:00.0000000 |
若要優化此查詢,我們可以如下所述將其重寫,讓時間範圍以聯結索引鍵表示。
重寫查詢以說明時間範圍
重寫查詢,以便將 datetime
值「離散化」至大小是時間範圍一半的貯體。 使用 Kusto equi-join
來比較這些貯體識別碼。
let lookupWindow = 1min;
let lookupBin = lookupWindow / 2.0; // lookup bin = equal to 1/2 of the lookup window
T
| where EventType == 'A'
| project SessionId, Start=Timestamp,
// TimeKey on the left side of the join is mapped to a discrete time axis for the join purpose
TimeKey = bin(Timestamp, lookupBin)
| join kind=inner
(
T
| where EventType == 'B'
| project SessionId, End=Timestamp,
// TimeKey on the right side of the join - emulates event 'B' appearing several times
// as if it was 'replicated'
TimeKey = range(bin(Timestamp-lookupWindow, lookupBin),
bin(Timestamp, lookupBin),
lookupBin)
// 'mv-expand' translates the TimeKey array range into a column
| mv-expand TimeKey to typeof(datetime)
) on SessionId, TimeKey
| where (End - Start) between (0min .. lookupWindow)
| project SessionId, Start, End
可執行的查詢參考 (具有內嵌資料表)
let T = datatable(SessionId:string, EventType:string, Timestamp:datetime)
[
'0', 'A', datetime(2017-10-01 00:00:00),
'0', 'B', datetime(2017-10-01 00:01:00),
'1', 'B', datetime(2017-10-01 00:02:00),
'1', 'A', datetime(2017-10-01 00:03:00),
'3', 'A', datetime(2017-10-01 00:04:00),
'3', 'B', datetime(2017-10-01 00:10:00),
];
let lookupWindow = 1min;
let lookupBin = lookupWindow / 2.0;
T
| where EventType == 'A'
| project SessionId, Start=Timestamp, TimeKey = bin(Timestamp, lookupBin)
| join kind=inner
(
T
| where EventType == 'B'
| project SessionId, End=Timestamp,
TimeKey = range(bin(Timestamp-lookupWindow, lookupBin),
bin(Timestamp, lookupBin),
lookupBin)
| mv-expand TimeKey to typeof(datetime)
) on SessionId, TimeKey
| where (End - Start) between (0min .. lookupWindow)
| project SessionId, Start, End
輸出
SessionId | 開始 | 結束 |
---|---|---|
0 | 2017-10-01 00:00:00.0000000 | 2017-10-01 00:01:00.0000000 |
5M 資料查詢
下一個查詢會模擬 5M 記錄和 ~1M 標識符的數據集,並使用上述技術執行查詢。
let T = range x from 1 to 5000000 step 1
| extend SessionId = rand(1000000), EventType = rand(3), Time=datetime(2017-01-01)+(x * 10ms)
| extend EventType = case(EventType < 1, "A",
EventType < 2, "B",
"C");
let lookupWindow = 1min;
let lookupBin = lookupWindow / 2.0;
T
| where EventType == 'A'
| project SessionId, Start=Time, TimeKey = bin(Time, lookupBin)
| join kind=inner
(
T
| where EventType == 'B'
| project SessionId, End=Time,
TimeKey = range(bin(Time-lookupWindow, lookupBin),
bin(Time, lookupBin),
lookupBin)
| mv-expand TimeKey to typeof(datetime)
) on SessionId, TimeKey
| where (End - Start) between (0min .. lookupWindow)
| project SessionId, Start, End
| count
輸出
Count |
---|
3344 |
意見反應
https://aka.ms/ContentUserFeedback。
即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應