Consulta de orden aleatorio

La shuffle consulta es una transformación de conservación semántica que se usa con un conjunto de operadores que admiten la shuffle estrategia. En función de los datos implicados, la consulta con la shuffle estrategia puede producir un mejor rendimiento. Es mejor usar la estrategia de consulta aleatoria cuando la shuffle clave (una join clave, summarize una clave, make-series una clave o partition una clave) tiene una cardinalidad alta y la consulta de operador normal alcanza los límites de consulta.

Puede usar los operadores siguientes con el comando shuffle:

Para usar la estrategia de shuffle consulta, agregue la expresión hint.strategy = shuffle o hint.shufflekey = <key>. Cuando se usa hint.strategy=shuffle, las claves ordenarán aleatoriamente los datos del operador. Use esta expresión cuando la clave compuesta sea única, pero cada clave no es lo suficientemente única, por lo que ordenará los datos mediante todas las claves del operador aleatorio.

Al crear particiones de datos con la estrategia aleatoria, la carga de datos se comparte en todos los nodos del clúster. Cada nodo procesa una partición de los datos. El número predeterminado de particiones es igual al número de nodos del clúster.

El número de partición se puede invalidar mediante la sintaxis hint.num_partitions = total_partitions, que controlará el número de particiones. Esto resulta útil cuando el clúster tiene un pequeño número de nodos de clúster y el número de particiones predeterminado será pequeño y la consulta produce un error o tarda mucho tiempo de ejecución.

Nota

El uso de muchas particiones puede consumir más recursos de clúster y degradar el rendimiento. Elija cuidadosamente el número de partición empezando por hint.strategy = shuffle y empiece a aumentar las particiones gradualmente.

En algunos casos, hint.strategy = shuffle se omite y la consulta no se ejecutará en shuffle la estrategia. Esto puede suceder cuando:

  • El join operador tiene otro shuffleoperador compatible (join, summarizemake-series o partition) en el lado izquierdo o en el lado derecho.
  • El summarize operador aparece después de otro shuffleoperador compatible (join, summarizemake-series o partition) en la consulta.

Syntax

Con hint.strategy = shuffle

T|DataExpression|joinhint.strategy = shuffle(DataExpression)

T|summarizehint.strategy = shuffleDataExpression

T|Consulta| partition hint.strategy( = shuffleSubQuery)

Con hint.shufflekey = clave

T|DataExpression|joinhint.shufflekey = Clave(DataExpression)

T|summarizehint.shufflekey = keyDataExpression

T|make-serieshint.shufflekey = keyDataExpression

T|Consulta|subconsultade clave( de partición hint.shufflekey = )

Obtenga más información sobre las convenciones de sintaxis.

Parámetros

Nombre Tipo Requerido Descripción
T string ✔️ Origen tabular cuyos datos va a procesar el operador.
DataExpression string Expresión de transformación tabular implícita o explícita.
Consultar string Una expresión de transformación se ejecuta en los registros de T.
key string Use una join clave, summarize una clave, make-series una clave o partition una clave.
Subconsulta string Expresión de transformación.

Nota

DataExpression o Query deben especificarse en función de la sintaxis elegida.

Ejemplos

Uso de summarize con orden aleatorio

La consulta de shuffle estrategia con summarize el operador comparte la carga en todos los nodos del clúster, donde cada nodo procesa una partición de los datos.

StormEvents
| summarize hint.strategy = shuffle count(), avg(InjuriesIndirect) by State
| count 

Salida

Count
67

Usar combinación con orden aleatorio

StormEvents
| where State has "West"
| where EventType has "Flood"
| join hint.strategy=shuffle 
    (
    StormEvents
    | where EventType has "Hail"
    | project EpisodeId, State, DamageProperty
    )
    on State
| count

Salida

Count
103

Uso de make-series con orden aleatorio

StormEvents
| where State has "North"
| make-series hint.shufflekey = State sum(DamageProperty) default = 0 on StartTime in range(datetime(2007-01-01 00:00:00.0000000), datetime(2007-01-31 23:59:00.0000000), 15d) by State

Salida

State sum_DamageProperty StartTime
NORTH DAKOTA [60000,0,0] ["2006-12-31T00:00:00.0000000Z","2007-01-15T00:00:00.0000000Z","2007-01-30T00:00:00.0000000Z"]
CAROLINA DEL NORTE [20000,0,1000] ["2006-12-31T00:00:00.0000000Z","2007-01-15T00:00:00.0000000Z","2007-01-30T00:00:00.0000000Z"]
ATLÁNTICO NORTE [0,0,0] ["2006-12-31T00:00:00.0000000Z","2007-01-15T00:00:00.0000000Z","2007-01-30T00:00:00.0000000Z"]

Uso de la partición con orden aleatorio

StormEvents
| partition hint.strategy=shuffle by EpisodeId
(
    top 3 by DamageProperty
    | project EpisodeId, State, DamageProperty
)
| count

Salida

Count
22345

Comparar hint.strategy=shuffle and hint.shufflekey=key

Cuando se usa hint.strategy=shuffle, el operador aleatorio se ordenará aleatoriamente por todas las claves. En el ejemplo siguiente, la consulta ordena los datos mediante EpisodeId y EventId como claves:

StormEvents
| where StartTime > datetime(2007-01-01 00:00:00.0000000)
| join kind = inner hint.strategy=shuffle (StormEvents | where DamageCrops > 62000000) on EpisodeId, EventId
| count

Salida

Count
14

En la siguiente consulta se usa hint.shufflekey = key. La consulta anterior es equivalente a esta consulta.

StormEvents
| where StartTime > datetime(2007-01-01 00:00:00.0000000)
| join kind = inner hint.shufflekey = EpisodeId hint.shufflekey = EventId (StormEvents | where DamageCrops > 62000000) on EpisodeId, EventId

Salida

Count
14

Orden aleatorio de los datos con varias claves

En algunos casos, hint.strategy=shuffle se omitirá y la consulta no se ejecutará en la estrategia de orden aleatorio. Por ejemplo, en el ejemplo siguiente, la combinación tiene un resumen en su lado izquierdo, por lo que el uso hint.strategy=shuffle de no aplicará la estrategia de orden aleatorio a la consulta:

StormEvents
| where StartTime > datetime(2007-01-01 00:00:00.0000000)
| summarize count() by EpisodeId, EventId
| join kind = inner hint.strategy=shuffle (StormEvents | where DamageCrops > 62000000) on EpisodeId, EventId

Salida

EpisodeId EventId ... EpisodeId1 EventId1 ...
1030 4407 ... 1030 4407 ...
1030 13721 ... 1030 13721 ...
2477 12530 ... 2477 12530 ...
2103 10237 ... 2103 10237 ...
2103 10239 ... 2103 10239 ...
... ... ... ... ... ...

Para solucionar este problema y ejecutar en la estrategia de orden aleatorio, elija la clave que es común para las summarize operaciones y join . En este caso, esta clave es EpisodeId. Use la sugerencia hint.shufflekey para especificar la clave de orden aleatorio en para joinhint.shufflekey = EpisodeId:

StormEvents
| where StartTime > datetime(2007-01-01 00:00:00.0000000)
| summarize count() by EpisodeId, EventId
| join kind = inner hint.shufflekey=EpisodeId (StormEvents | where DamageCrops > 62000000) on EpisodeId, EventId

Salida

EpisodeId EventId ... EpisodeId1 EventId1 ...
1030 4407 ... 1030 4407 ...
1030 13721 ... 1030 13721 ...
2477 12530 ... 2477 12530 ...
2103 10237 ... 2103 10237 ...
2103 10239 ... 2103 10239 ...
... ... ... ... ... ...

Uso de summarize con orden aleatorio para mejorar el rendimiento

En este ejemplo, el uso del operador con shuffle estrategia mejora el summarize rendimiento. La tabla de origen tiene 150 millones de registros y la cardinalidad del grupo por clave es de 10 M, que se distribuye en 10 nodos de clúster.

El summarize uso del operador sin shuffle estrategia, la consulta finaliza después de las 1:08 y el pico de uso de memoria es de ~3 GB:

orders
| summarize arg_max(o_orderdate, o_totalprice) by o_custkey 
| where o_totalprice < 1000
| count

Salida

Count
1086

Al usar shuffle la estrategia con summarize, la consulta finaliza después de unos 7 segundos y el pico de uso de memoria es de 0,43 GB:

orders
| summarize hint.strategy = shuffle arg_max(o_orderdate, o_totalprice) by o_custkey 
| where o_totalprice < 1000
| count

Salida

Count
1086

En el ejemplo siguiente se muestra el rendimiento en un clúster que tiene dos nodos de clúster, con una tabla que tiene 60 millones de registros, donde la cardinalidad del grupo por clave es 2M.

La ejecución de la consulta sin hint.num_partitions solo usará dos particiones (como número de nodos de clúster) y la consulta siguiente tardará unos 1:10 minutos:

lineitem 
| summarize hint.strategy = shuffle dcount(l_comment), dcount(l_shipdate) by l_partkey 
| consume

Si establece el número de particiones en 10, la consulta finalizará después de 23 segundos:

lineitem 
| summarize hint.strategy = shuffle hint.num_partitions = 10 dcount(l_comment), dcount(l_shipdate) by l_partkey 
| consume

Uso de combinación con orden aleatorio para mejorar el rendimiento

En el ejemplo siguiente se muestra cómo el uso shuffle de la estrategia con el operador mejora el join rendimiento.

Los ejemplos se muestrearon en un clúster con 10 nodos donde los datos se reparten entre todos estos nodos.

La tabla de origen del lado izquierdo de la consulta tiene registros de 15 M donde la cardinalidad de la join clave es ~14M. El origen del lado derecho de la consulta tiene 150 millones de registros y la cardinalidad de la join clave es de 10 M. La consulta finaliza después de aproximadamente 28 segundos y el pico de uso de memoria es de 1,43 GB:

customer
| join
    orders
on $left.c_custkey == $right.o_custkey
| summarize sum(c_acctbal) by c_nationkey

Cuando se usa shuffle la estrategia con un join operador, la consulta finaliza después de aproximadamente 4 segundos y el pico de uso de memoria es de 0,3 GB:

customer
| join
    hint.strategy = shuffle orders
on $left.c_custkey == $right.o_custkey
| summarize sum(c_acctbal) by c_nationkey

En otro ejemplo, se prueban las mismas consultas en un conjunto de datos mayor con las siguientes condiciones:

  • El origen izquierdo de join es 150M y la cardinalidad de la clave es 148M.
  • El origen derecho de join es 1,5B y la cardinalidad de la clave es ~100M.

La consulta con solo el join operador alcanza los límites y agota el tiempo de espera después de 4 minutos. Sin embargo, al usar shuffle la estrategia con el join operador , la consulta finaliza después de aproximadamente 34 segundos y el pico de uso de memoria es de 1,23 GB.

En el ejemplo siguiente se muestra la mejora en un clúster que tiene dos nodos de clúster, con una tabla de 60 millones de registros, donde la cardinalidad de la join clave es 2M. La ejecución de la consulta sin hint.num_partitions solo usará dos particiones (como número de nodos de clúster) y la consulta siguiente tardará unos 1:10 minutos:

lineitem
| summarize dcount(l_comment), dcount(l_shipdate) by l_partkey
| join
    hint.shufflekey = l_partkey   part
on $left.l_partkey == $right.p_partkey
| consume

Al establecer el número de particiones en 10, la consulta finalizará después de 23 segundos:

lineitem
| summarize dcount(l_comment), dcount(l_shipdate) by l_partkey
| join
    hint.shufflekey = l_partkey  hint.num_partitions = 10    part
on $left.l_partkey == $right.p_partkey
| consume