Partager via


shuffle, requête

La shuffle requête est une transformation de conservation sémantique utilisée avec un ensemble d’opérateurs qui prennent en charge la shuffle stratégie. Selon les données impliquées, l’interrogation avec la stratégie peut améliorer les shuffle performances. Il est préférable d’utiliser la stratégie de requête aléatoire lorsque la shuffle clé (clé join , clé, summarize make-series clé ou partition clé) a une cardinalité élevée et que la requête opérateur régulière atteint les limites de requête.

Vous pouvez utiliser les opérateurs suivants avec la commande shuffle :

Pour utiliser la stratégie de shuffle requête, ajoutez l’expression hint.strategy = shuffle ou hint.shufflekey = <key>. Lorsque vous utilisez hint.strategy=shuffle, les données de l’opérateur sont aléatoires par toutes les clés. Utilisez cette expression lorsque la clé composée est unique, mais que chaque clé n’est pas suffisamment unique, vous allez donc mélanger les données à l’aide de toutes les clés de l’opérateur aléatoire.

Lors du partitionnement de données avec la stratégie de shuffle, le chargement des données est partagé sur tous les nœuds de cluster. Chaque nœud traite une partition des données. Le nombre de partitions par défaut est égal au nombre de nœuds de cluster.

Le numéro de partition peut être substitué à l’aide de la syntaxe hint.num_partitions = total_partitions, qui contrôlera le nombre de partitions. Cela est utile lorsque le cluster a un petit nombre de nœuds de cluster et que le nombre de partitions par défaut est petit, et que la requête échoue ou prend beaucoup de temps d’exécution.

Remarque

L’utilisation de nombreuses partitions peut consommer davantage de ressources de cluster et dégrader les performances. Choisissez attentivement le numéro de partition en commençant par le hint.strategy = shuffle début et en augmentant progressivement les partitions.

Dans certains cas, la hint.strategy = shuffle valeur est ignorée et la requête ne s’exécute pas dans la shuffle stratégie. Ceci peut se produire quand :

  • L’opérateur join a un autre shuffleopérateur -compatible (join, summarizemake-series ou partition) sur le côté gauche ou le côté droit.
  • L’opérateur summarize apparaît après un autre shuffleopérateur compatible (join, make-series summarizeou partition) dans la requête.

Syntaxe

Avec hint.strategy = shuffle

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

T = | summarize hint.strategyshuffle DataExpression

Sous-requête | de partition T | hint.strategy = shuffle( )

Avec hint.shufflekey = la clé

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

T hint.shufflekeysummarize = | key DataExpression

T hint.shufflekeymake-series = | key DataExpression

Sous-requête de la clé ( de partition T | hint.shufflekey = | )

En savoir plus sur les conventions de syntaxe.

Paramètres

Nom Type Requise Description
T string ✔️ Source tabulaire dont les données doivent être traitées par l’opérateur.
DataExpression string Expression de transformation tabulaire implicite ou explicite.
Requête string Une expression de transformation s’exécute sur les enregistrements de T.
key string Utilisez une clé, summarize une clé, make-series une join clé ou partition une clé.
Sous-requête string Expression de transformation.

Remarque

DataExpression ou Query doit être spécifié en fonction de la syntaxe choisie.

Exemples

Utiliser la synthèse avec le shuffle

La shuffle requête de stratégie avec summarize l’opérateur partage la charge sur tous les nœuds de cluster, où chaque nœud traite une partition des données.

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

Sortie

Count
67

Utiliser la jointure avec le shuffle

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

Sortie

Count
103

Utiliser la série make-series avec shuffle

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

Sortie

State sum_DamageProperty StartTime
DAKOTA DU NORD [60000,0,0] ["2006-12-31T00:00:00.000000Z »,"2007-01-15T00:00:00.0000000Z »,"2007-01-30T00:00:00.000000Z"]
CAROLINE DU NORD [20000,0,1000] ["2006-12-31T00:00:00.000000Z »,"2007-01-15T00:00:00.0000000Z »,"2007-01-30T00:00:00.000000Z"]
ATLANTIQUE NORD [0,0,0] ["2006-12-31T00:00:00.000000Z »,"2007-01-15T00:00:00.0000000Z »,"2007-01-30T00:00:00.000000Z"]

Utiliser une partition avec un shuffle

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

Sortie

Count
22345

Comparer hint.strategy=shuffle et hint.shufflekey=key

Lorsque vous utilisez hint.strategy=shuffle, l’opérateur shuffled est mélangé par toutes les clés. Dans l’exemple suivant, la requête mélange les données à l’aide des clés EpisodeId et EventId des clés :

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

Sortie

Count
14

La requête suivante utilise hint.shufflekey = key. La requête ci-dessus équivaut à cette requête.

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

Sortie

Count
14

Mélanger les données avec plusieurs clés

Dans certains cas, la hint.strategy=shuffle requête est ignorée et la requête ne s’exécute pas dans la stratégie de shuffle. Par exemple, dans l’exemple suivant, la jointure a résumé sur son côté gauche. Par conséquent, l’utilisation hint.strategy=shuffle n’applique pas de stratégie de shuffle à la requête :

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

Sortie

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

Pour surmonter ce problème et exécuter dans une stratégie de shuffle, choisissez la clé courante pour les opérations et join les summarize opérations. Dans ce cas, cette clé est EpisodeId. Utilisez l’indicateur hint.shufflekey pour spécifier la clé de shuffle sur l’élément join à hint.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

Sortie

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

Utiliser la synthèse avec le shuffle pour améliorer les performances

Dans cet exemple, l’utilisation de l’opérateur summarize avec shuffle une stratégie améliore les performances. La table source a 150 Millions d’enregistrements et la cardinalité du groupe par clé est de 10 M, qui est répartie sur 10 nœuds de cluster.

L’utilisation d’un summarize opérateur sans shuffle stratégie se termine après 1:08 et le pic d’utilisation de la mémoire est d’environ 3 Go :

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

Sortie

Count
1086

Lors de l’utilisation de shuffle la stratégie avec summarize, la requête se termine après environ 7 secondes et le pic d’utilisation de la mémoire est de 0,43 Go :

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

Sortie

Count
1086

L’exemple suivant illustre les performances sur un cluster qui a deux nœuds de cluster, avec une table qui a 60 Millions d’enregistrements, où la cardinalité du groupe par clé est de 2M.

L’exécution de la requête sans hint.num_partitions utiliser seulement deux partitions (en tant que numéro de nœuds de cluster) et la requête suivante prend environ 1:10 minutes :

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

Si vous définissez le numéro de partition sur 10, la requête se termine après 23 secondes :

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

Utiliser la jointure avec le shuffle pour améliorer les performances

L’exemple suivant montre comment utiliser shuffle la stratégie avec l’opérateur join améliore les performances.

Les exemples ont été échantillonné sur un cluster avec 10 nœuds où les données sont réparties sur tous ces nœuds.

La table source gauche de la requête a 15 Millions d’enregistrements où la cardinalité de la join clé est ~14M. La source de droite de la requête a 150 Millions d’enregistrements et la cardinalité de la join clé est de 10 M. La requête se termine après ~28 secondes et le pic d’utilisation de la mémoire est de 1,43 Go :

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

Lorsque vous utilisez shuffle une stratégie avec un join opérateur, la requête se termine après environ 4 secondes et le pic d’utilisation de la mémoire est de 0,3 Go :

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

Dans un autre exemple, nous essayons les mêmes requêtes sur un jeu de données plus volumineux avec les conditions suivantes :

  • La source gauche de la join clé est de 150M et la cardinalité de la clé est de 148M.
  • La source de droite de la join clé est de 1,5B, et la cardinalité de la clé est ~100M.

La requête avec seulement l’opérateur join atteint les limites et expire après 4 minutes. Toutefois, lors de l’utilisation shuffle de la stratégie avec l’opérateur join , la requête se termine après environ 34 secondes et le pic d’utilisation de la mémoire est de 1,23 Go.

L’exemple suivant montre l’amélioration sur un cluster qui a deux nœuds de cluster, avec une table de 60 M d’enregistrements, où la cardinalité de la join clé est de 2M. L’exécution de la requête sans hint.num_partitions utiliser seulement deux partitions (en tant que numéro de nœuds de cluster) et la requête suivante prend environ 1:10 minutes :

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

Lorsque vous définissez le numéro de partition sur 10, la requête se termine après 23 secondes :

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