Combinación de período de tiempo
Se aplica a: ✅Microsoft Fabric✅Azure Data Explorer✅Azure Monitor✅Microsoft Sentinel
A menudo resulta útil combinar entre dos conjuntos de datos grandes en alguna clave de cardinalidad alta, como un identificador de operación o un identificador de sesión, y limitar aún más los registros del lado derecho ($right) que deben coincidir con cada registro del lado izquierdo ($left) agregando una restricción en la "distancia de tiempo" entre datetime
columnas de la izquierda y a la derecha.
La operación anterior difiere de la operación de combinación habitual, ya que para la equi-join
parte de la coincidencia de la clave de alta cardinalidad entre los conjuntos de datos izquierdo y derecho, el sistema también puede aplicar una función de distancia y usarla para acelerar considerablemente la combinación.
Nota
Una función de distancia no se comporta como la igualdad (es decir, cuando tanto dist(x,y) como dist(y,z) son true, no sigue que dist(x,z) también sea true). Esto se conoce a veces como una "combinación diagonal".
Ejemplo para identificar secuencias de eventos sin período de tiempo
Para identificar secuencias de eventos dentro de un período de tiempo relativamente pequeño, en este ejemplo se usa una tabla T
con el esquema siguiente:
-
SessionId
: una columna de tipostring
con identificadores de correlación. -
EventType
: columna de tipostring
que identifica el tipo de evento del registro. -
Timestamp
: una columna de tipodatetime
indica cuándo se produjo el evento descrito por el registro.
SessionId | EventType | Timestamp |
---|---|---|
0 | Un | 2017-10-01T00:00:00Z |
0 | B | 2017-10-01T00:01:00Z |
1 | B | 2017-10-01T00:02:00Z |
1 | Un | 2017-10-01T00:03:00Z |
3 | Un | 2017-10-01T00:04:00Z |
3 | B | 2017-10-01T00:10:00Z |
La consulta siguiente crea el conjunto de datos y, a continuación, identifica todos los identificadores de sesión en los que el tipo de evento A
fue seguido de un tipo de evento B
dentro de un período de tiempo de 1min
.
Ejecutar el 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 salida
SessionId | Empezar | Fin |
---|---|---|
0 | 2017-10-01 00:00:00.0000000 | 2017-10-01 00:01:00.0000000 |
Ejemplo optimizado con ventana de tiempo
Para optimizar esta consulta, podemos volver a escribirla para tener en cuenta el período de tiempo. El período de tiempo de THe se expresa como una clave de combinación. Vuelva a escribir la consulta para que los valores de datetime
sean "discretizados" en cubos cuyo tamaño sea la mitad del tamaño de la ventana de tiempo. Use equi-join
para comparar los identificadores de cubo.
La consulta busca pares de eventos dentro de la misma sesión (SessionId) donde un evento "A" va seguido de un evento "B" en un minuto. Proyecta el identificador de sesión, la hora de inicio del evento "A" y la hora de finalización del evento "B".
Ejecutar el 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 salida
SessionId | Empezar | Fin |
---|---|---|
0 | 2017-10-01 00:00:00.0000000 | 2017-10-01 00:01:00.0000000 |
5 millones de consultas de datos
La siguiente consulta emula un amplio conjunto de datos de registros de 5M y aproximadamente 1M de identificadores de sesión y ejecuta la consulta con la técnica de período de tiempo.
Ejecutar el 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 salida
Contar |
---|
3344 |