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 shuffle stratégie peut générer de meilleures performances. Il est préférable d’utiliser la stratégie de requête aléatoire lorsque la shuffle clé (une clé, une clé, summarize une join clé ou make-seriespartition une clé) présente une cardinalité élevée et que la requête de l’opérateur normal 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 mélangées 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 lecture aléatoire, la charge de données est partagée sur tous les nœuds de cluster. Chaque nœud traite une partition des données. Le nombre par défaut de partitions est égal au nombre de nœuds de cluster.

Le numéro de partition peut être remplacé à 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 un temps d’exécution long.

Notes

L’utilisation de nombreuses partitions peut consommer plus de ressources de cluster et dégrader les performances. Choisissez soigneusement le numéro de partition en commençant par et hint.strategy = shuffle commencez à augmenter les partitions progressivement.

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

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

Syntax

Avec hint.strategy = shuffle

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

T|summarizehint.strategy = shuffleDataExpression

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

Avec hint.shufflekey = la clé

T|DataExpression|joinhint.shufflekey = Clé(DataExpression)

T|summarizehint.shufflekey = cléDataExpression

T|make-serieshint.shufflekey = cléDataExpression

T|Requête|sous-requête declé( de partition hint.shufflekey = )

Découvrez les conventions de syntaxe.

Paramètres

Nom Type Obligatoire 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 Expression de transformation exécutée sur les enregistrements de T.
key string Utilisez une clé, summarize une join clé, make-series une clé ou partition une clé.
Sous-requête string Expression de transformation.

Notes

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

Exemples

Utiliser résumer avec un mélange aléatoire

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 mélange aléatoire

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 des 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.000000000Z »,"2007-01-15T00 :200700 :00.0000000Z »,"2007-01-30T00 :00 :00.00000000Z"]
CAROLINE DU NORD [20000,0,1000] ["2006-12-31T00 :00 :00.000000000Z »,"2007-01-15T00 :200700 :00.0000000Z »,"2007-01-30T00 :00 :00.00000000Z"]
ATLANTIQUE NORD [0,0,0] ["2006-12-31T00 :00 :00.000000000Z »,"2007-01-15T00 :200700 :00.0000000Z »,"2007-01-30T00 :00 :00.00000000Z"]

Utiliser la partition avec le 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 aléatoire est mélangé par toutes les clés. Dans l’exemple suivant, la requête mélange les données à l’aide EpisodeId de clés et EventId en tant que 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, le hint.strategy=shuffle est ignoré et la requête ne s’exécute pas dans la stratégie de lecture aléatoire. Par exemple, dans l’exemple suivant, la jointure a un résumé sur son côté gauche, de sorte que l’utilisation hint.strategy=shuffle n’applique pas de stratégie de lecture aléatoire à 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 résoudre ce problème et exécuter une stratégie de lecture aléatoire, choisissez la clé courante pour les summarize opérations et join . Dans ce cas, cette clé est EpisodeId. Utilisez l’indicateur hint.shufflekey pour spécifier la touche de lecture aléatoire sur le 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 résumé avec shuffle pour améliorer les performances

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

À l’aide summarize de l’opérateur sans shuffle stratégie, la requête 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 au bout d’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 d’un cluster qui a deux nœuds de cluster, avec une table contenant 60 millions d’enregistrements, où la cardinalité du groupe par clé est de 2 M.

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

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

Si vous définissez le numéro de partitions 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 join with shuffle pour améliorer les performances

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

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

La table source de gauche de la requête comporte 15 millions d’enregistrements où la cardinalité de la join clé est d’environ 14 millions. La source de droite de la requête a 150 Millions d’enregistrements et la cardinalité de la join clé est de 10 Millions. La requête se termine après environ 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 de gauche du est de join 150M et la cardinalité de la clé est de 148M.
  • La source de droite du join est 1,5B et la cardinalité de la clé est d’environ 100M.

La requête avec uniquement l’opérateur join atteint les limites et les délais d’expiration après 4 minutes. Toutefois, lorsque vous utilisez shuffle 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 d’un cluster qui a deux nœuds de cluster, avec une table de 60 Millions d’enregistrements, où la cardinalité de la join clé est de 2M. L’exécution de la requête sans hint.num_partitions n’utilise que deux partitions (comme numéro de nœuds de cluster) et la requête suivante prend environ 1 min 10 :

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 partitions 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