Junção da janela de tempo
Aplica-se a: ✅Microsoft Fabric✅Azure Data Explorer✅Azure Monitor✅Microsoft Sentinel
Geralmente, é útil unir entre dois grandes conjuntos de dados em alguma chave de alta cardinalidade, como uma ID de operação ou uma ID de sessão, e limitar ainda mais os registros do lado direito ($right) que precisam corresponder a cada registro do lado esquerdo ($left) adicionando uma restrição à "distância de tempo" entre datetime
colunas à esquerda e à direita.
A operação acima difere da operação de junção usual, uma vez que para a parte equi-join
da correspondência da chave de alta cardinalidade entre os conjuntos de dados esquerdo e direito, o sistema também pode aplicar uma função de distância e usá-la para acelerar consideravelmente a junção.
Nota
Uma função de distância não se comporta como igualdade (ou seja, quando dist(x,y) e dist(y,z) são verdadeiras, ela não segue que dist(x,z) também é verdadeiro.) Às vezes, isso é chamado de "junção diagonal".
Exemplo para identificar sequências de eventos sem janela de tempo
Para identificar sequências de eventos em uma janela de tempo relativamente pequena, este exemplo usa uma tabela T
com o seguinte esquema:
-
SessionId
: uma coluna do tipostring
com IDs de correlação. -
EventType
: uma coluna do tipostring
que identifica o tipo de evento do registro. -
Timestamp
: uma coluna do tipodatetime
indica quando o evento descrito pelo registro ocorreu.
SessionId | EventType | Timestamp |
---|---|---|
0 | Um | 2017-10-01T00:00:00Z |
0 | B | 2017-10-01T00:01:00Z |
1 | B | 2017-10-01T00:02:00Z |
1 | Um | 2017-10-01T00:03:00Z |
3 | Um | 2017-10-01T00:04:00Z |
3 | B | 2017-10-01T00:10:00Z |
A consulta a seguir cria o conjunto de dados e identifica todas as IDs de sessão nas quais o tipo de evento A
foi seguido por um tipo de evento B
dentro de uma janela de tempo 1min
.
executar o de consulta
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
| 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
de saída
SessionId | Começar | Fim |
---|---|---|
0 | 2017-10-01 00:00:00.0000000 | 2017-10-01 00:01:00.0000000 |
Exemplo otimizado com a janela de tempo
Para otimizar essa consulta, podemos reescrevê-la para levar em conta a janela de tempo. A janela de tempo THe é expressa como uma chave de junção. Reescreva a consulta para que os valores de datetime
sejam "discretos" em buckets cujo tamanho seja metade do tamanho da janela de tempo. Use equi-join
para comparar as IDs do bucket.
A consulta localiza pares de eventos na mesma sessão (SessionId) em que um evento 'A' é seguido por um evento 'B' dentro de 1 minuto. Ele projeta a ID da sessão, a hora de início do evento 'A' e a hora de término do evento 'B'.
executar o de consulta
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
de saída
SessionId | Começar | Fim |
---|---|---|
0 | 2017-10-01 00:00:00.0000000 | 2017-10-01 00:01:00.0000000 |
Consulta de dados de 5 milhões
A próxima consulta emula um amplo conjunto de dados de registros de 5M e IDs de sessão de aproximadamente 1M e executa a consulta com a técnica da janela de tempo.
executar o de consulta
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
de saída
Contar |
---|
3344 |