Shuffleabfrage
Gilt für: ✅Microsoft Fabric✅Azure Data Explorer✅Azure Monitor✅Microsoft Sentinel
Die shuffle
Abfrage ist eine semantische Transformation, die mit einer Reihe von Operatoren verwendet wird, die die shuffle
Strategie unterstützen. Je nach den beteiligten Daten kann die Abfrage mit der shuffle
Strategie eine bessere Leistung erzielen. Es ist besser, die Shuffle-Abfragestrategie zu verwenden, wenn der shuffle
Schlüssel (schlüssel join
, Schlüssel, summarize
Schlüssel, make-series
Schlüssel oder partition
Schlüssel) eine hohe Kardinalität aufweist und die reguläre Operatorabfrage Abfragegrenzwerte erreicht.
Sie können die folgenden Operatoren mit dem Befehl "Shuffle" verwenden:
Um die shuffle
Abfragestrategie zu verwenden, fügen Sie den Ausdruck hint.strategy = shuffle
oder hint.shufflekey = <key>
. Bei Verwendung hint.strategy=shuffle
werden die Operatordaten von allen Schlüsseln neu angeordnet. Verwenden Sie diesen Ausdruck, wenn der Verbundschlüssel eindeutig ist, aber jeder Schlüssel nicht eindeutig genug ist, sodass Sie die Daten mit allen Schlüsseln des shuffled-Operators mischen.
Beim Partitionieren von Daten mit der Shuffle-Strategie wird die Datenlast auf allen Clusterknoten freigegeben. Jeder Knoten verarbeitet eine Partition der Daten. Die Standardanzahl der Partitionen entspricht der Anzahl der Clusterknoten.
Die Partitionsnummer kann mithilfe der Syntax hint.num_partitions = total_partitions
überschrieben werden, die die Anzahl der Partitionen steuert. Dies ist nützlich, wenn der Cluster über eine kleine Anzahl von Clusterknoten verfügt und die Standardpartitionsnummer klein ist, und die Abfrage schlägt fehl oder dauert eine lange Ausführungszeit.
Hinweis
Die Verwendung vieler Partitionen verbraucht möglicherweise mehr Clusterressourcen und beeinträchtigt die Leistung. Wählen Sie die Partitionsnummer sorgfältig aus, indem Sie mit der hint.strategy = shuffle
schrittweisen Erhöhung der Partitionen beginnen.
In einigen Fällen wird die hint.strategy = shuffle
Abfrage ignoriert, und die Abfrage wird nicht in shuffle
der Strategie ausgeführt. Dies kann passieren, wenn:
- Der
join
Operator verfügt über einen anderenshuffle
kompatiblen Operator (join
,summarize
make-series
oderpartition
) auf der linken oder rechten Seite. - Der
summarize
Operator wird nach einem anderenshuffle
kompatiblen Operator (join
,make-series
summarize
oderpartition
) in der Abfrage angezeigt.
Syntax
Mit hint.strategy
= shuffle
T |
DataExpression DataExpression |
join
hint.strategy
= shuffle
(
)
T = |
summarize
hint.strategy
shuffle
DataExpression
T |
Query |
Partition hint.strategy
= (
shuffle
SubQuery )
Mit hint.shufflekey
= Taste
T |
DataExpression = join
|
hint.shufflekey
Key (
DataExpression )
T hint.shufflekey
summarize
= |
key DataExpression
T hint.shufflekey
make-series
= |
key DataExpression
T |
Query |
Partition hint.shufflekey
= Key (
SubQuery )
Erfahren Sie mehr über Syntaxkonventionen.
Parameter
Name | Type | Erforderlich | Beschreibung |
---|---|---|---|
T | string |
✔️ | Die tabellarische Quelle, deren Daten vom Operator verarbeitet werden sollen. |
DataExpression | string |
Ein impliziter oder expliziter Tabellarischer Transformationsausdruck. | |
Abfrage | string |
Ein Transformationsausdruck wird für die Datensätze von T ausgeführt. | |
key | string |
Verwenden Sie eine join Taste, summarize eine Taste, make-series eine Taste oder partition eine Taste. |
|
SubQuery | string |
Ein Transformationsausdruck. |
Hinweis
Entweder DataExpression oder Query muss je nach ausgewählter Syntax angegeben werden.
Beispiele
Zusammenfassung mit "Shuffle" verwenden
Die shuffle
Strategieabfrage mit summarize
Operator teilt die Last auf allen Clusterknoten, wobei jeder Knoten eine Partition der Daten verarbeitet.
StormEvents
| summarize hint.strategy = shuffle count(), avg(InjuriesIndirect) by State
| count
Ausgabe
Anzahl |
---|
67 |
Verwenden der Verknüpfung mit "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
Ausgabe
Anzahl |
---|
103 |
Verwenden von Make-Series mit 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
Ausgabe
State | sum_DamageProperty | StartTime |
---|---|---|
NORTH DAKOTA | [60000,0,0] | ["2006-12-31T00:00:00.000000Z","2007-01-15T00:0100:00.000000Z","2007-01-30T00:00:00.000000Z"] |
NORTH CAROLINA | [20000,0,1000] | ["2006-12-31T00:00:00.000000Z","2007-01-15T00:0100:00.000000Z","2007-01-30T00:00:00.000000Z"] |
ATLANTIC NORTH | [0,0,0] | ["2006-12-31T00:00:00.000000Z","2007-01-15T00:0100:00.000000Z","2007-01-30T00:00:00.000000Z"] |
Verwenden der Partition mit "Shuffle"
StormEvents
| partition hint.strategy=shuffle by EpisodeId
(
top 3 by DamageProperty
| project EpisodeId, State, DamageProperty
)
| count
Ausgabe
Anzahl |
---|
22345 |
Vergleichen Sie "hint.strategy=shuffle" und "hint.shufflekey=key".
Wenn Sie dies verwenden hint.strategy=shuffle
, wird der shuffled-Operator von allen Tasten neu angeordnet. Im folgenden Beispiel löscht die Abfrage die Daten mit beiden EpisodeId
und EventId
als Schlüssel:
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
Ausgabe
Anzahl |
---|
14 |
Die folgende Abfrage verwendet hint.shufflekey = key
. Die obige Abfrage entspricht dieser Abfrage.
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
Ausgabe
Anzahl |
---|
14 |
Koppeln der Daten mit mehreren Schlüsseln
In einigen Fällen wird die hint.strategy=shuffle
Abfrage ignoriert, und die Abfrage wird nicht in der Shuffle-Strategie ausgeführt. Im folgenden Beispiel hat die Verknüpfung beispielsweise eine Zusammenfassung auf der linken Seite, sodass die Verwendung hint.strategy=shuffle
keine Shuffle-Strategie auf die Abfrage anwendet:
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
Output
EpisodeId | EventId | ... | EpisodeId1 | EventId1 | ... |
---|---|---|---|---|---|
1030 | 4407 | ... | 1030 | 4407 | ... |
1030 | 13721 | ... | 1030 | 13721 | ... |
2477 | 12530 | ... | 2477 | 12530 | ... |
2103 | 10237 | ... | 2103 | 10237 | ... |
2103 | 10239 | ... | 2103 | 10239 | ... |
... | ... | ... | ... | ... | ... |
Um dieses Problem zu überwinden und in der Shuffle-Strategie auszuführen, wählen Sie den Schlüssel aus, der für die und join
die summarize
Vorgänge üblich ist. In diesem Fall ist EpisodeId
dieser Schlüssel . Verwenden Sie den Hinweishint.shufflekey
, um die Shuffle-Taste für folgendes hint.shufflekey = EpisodeId
join
anzugeben:
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
Output
EpisodeId | EventId | ... | EpisodeId1 | EventId1 | ... |
---|---|---|---|---|---|
1030 | 4407 | ... | 1030 | 4407 | ... |
1030 | 13721 | ... | 1030 | 13721 | ... |
2477 | 12530 | ... | 2477 | 12530 | ... |
2103 | 10237 | ... | 2103 | 10237 | ... |
2103 | 10239 | ... | 2103 | 10239 | ... |
... | ... | ... | ... | ... | ... |
Verwenden von "Zusammenfassung" mit "Shuffle" zur Verbesserung der Leistung
In diesem Beispiel verbessert die Verwendung des Operators mit shuffle
der Strategie die summarize
Leistung. Die Quelltabelle verfügt über 150M-Datensätze und die Kardinalität der Gruppe nach Schlüssel beträgt 10M, die sich über 10 Clusterknoten erstreckt.
Bei Verwendung des summarize
Operators ohne shuffle
Strategie endet die Abfrage nach 1:08, und der Speicherauslastungs-Höchstwert beträgt ca. 3 GB:
orders
| summarize arg_max(o_orderdate, o_totalprice) by o_custkey
| where o_totalprice < 1000
| count
Output
Anzahl |
---|
1086 |
Während der Verwendung der shuffle
Strategie mit summarize
, endet die Abfrage nach ~7 Sekunden und der Speicherauslastungs-Höchstwert beträgt 0,43 GB:
orders
| summarize hint.strategy = shuffle arg_max(o_orderdate, o_totalprice) by o_custkey
| where o_totalprice < 1000
| count
Output
Anzahl |
---|
1086 |
Das folgende Beispiel veranschaulicht die Leistung eines Clusters mit zwei Clusterknoten mit einer Tabelle mit 60M-Datensätzen, wobei die Kardinalität der Gruppe nach Schlüssel 2M ist.
Wenn Sie die Abfrage ausführen, ohne hint.num_partitions
dass nur zwei Partitionen (als Clusterknotennummer) verwendet werden, dauert die folgende Abfrage ca. 1:10 Minuten:
lineitem
| summarize hint.strategy = shuffle dcount(l_comment), dcount(l_shipdate) by l_partkey
| consume
Wenn die Partitionsnummer auf 10 festgelegt wird, endet die Abfrage nach 23 Sekunden:
lineitem
| summarize hint.strategy = shuffle hint.num_partitions = 10 dcount(l_comment), dcount(l_shipdate) by l_partkey
| consume
Verwenden der Verknüpfung mit "Shuffle" zur Verbesserung der Leistung
Das folgende Beispiel zeigt, wie die Verwendung der shuffle
Strategie mit dem Operator die join
Leistung verbessert.
Die Beispiele wurden auf einem Cluster mit 10 Knoten beispielt, in denen die Daten über alle diese Knoten verteilt sind.
Die linke Quelltabelle der Abfrage verfügt über 15M-Datensätze, bei denen die Kardinalität des join
Schlüssels ~14M beträgt. Die rechte Quelle der Abfrage weist 150M Datensätze auf, und die Kardinalität des join
Schlüssels beträgt 10M. Die Abfrage endet nach ~28 Sekunden und der Speicherauslastungs-Höchstwert beträgt 1,43 GB:
customer
| join
orders
on $left.c_custkey == $right.o_custkey
| summarize sum(c_acctbal) by c_nationkey
Bei der Verwendung der shuffle
Strategie mit einem join
Operator endet die Abfrage nach ~4 Sekunden, und der Speicherauslastungs-Höchstwert beträgt 0,3 GB:
customer
| join
hint.strategy = shuffle orders
on $left.c_custkey == $right.o_custkey
| summarize sum(c_acctbal) by c_nationkey
In einem anderen Beispiel versuchen wir dieselben Abfragen für ein größeres Dataset mit den folgenden Bedingungen:
- Linksseitige Quelle der
join
150M und die Kardinalität des Schlüssels beträgt 148M. - Rechtsseitige Quelle des Schlüssels
join
ist 1,5B, und die Kardinalität des Schlüssels beträgt ~100M.
Die Abfrage mit nur dem join
Operator trifft Grenzwerte und Zeitüberschreitungen nach 4 Minuten. Wenn Sie die Strategie jedoch mit dem join
Operator verwendenshuffle
, endet die Abfrage nach ~34 Sekunden, und der Speicherauslastungs-Höchstwert beträgt 1,23 GB.
Das folgende Beispiel zeigt die Verbesserung auf einem Cluster mit zwei Clusterknoten mit einer Tabelle von 60M-Datensätzen, bei denen die Kardinalität des join
Schlüssels 2M ist.
Wenn Sie die Abfrage ausführen, ohne hint.num_partitions
dass nur zwei Partitionen (als Clusterknotennummer) verwendet werden, dauert die folgende Abfrage ca. 1:10 Minuten:
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
Wenn Die Partitionsnummer auf 10 festgelegt wird, endet die Abfrage nach 23 Sekunden:
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