Запрос shuffle
Область применения: ✅Microsoft Fabric✅Azure Data Explorer✅Azure Monitor✅Microsoft Sentinel
Запрос shuffle
— это семантическое преобразование, используемое с набором операторов, поддерживающих стратегию shuffle
. В зависимости от используемых данных запросы с shuffle
помощью стратегии могут повысить производительность. Лучше использовать стратегию перетасовки запросов, если shuffle
ключ, ключ join
, ключ, summarize
make-series
ключ или partition
ключ) имеет высокую кратность, а обычный запрос оператора достигает ограничений запросов.
С помощью команды перетасовки можно использовать следующие операторы:
Чтобы использовать стратегию shuffle
запроса, добавьте выражение hint.strategy = shuffle
или hint.shufflekey = <key>
. При использовании hint.strategy=shuffle
данные оператора будут перемешаны всеми ключами. Используйте это выражение, если составной ключ является уникальным, но каждый ключ не является достаточно уникальным, поэтому вы будете перетасовывайте данные с помощью всех ключей оператора перетасовки.
При секционирования данных с помощью стратегии перетасовки загрузка данных используется на всех узлах кластера. Каждый узел обрабатывает одну секцию данных. Число секций по умолчанию равно количеству узлов кластера.
Номер секции можно переопределить с помощью синтаксиса hint.num_partitions = total_partitions
, который будет контролировать количество секций. Это полезно, если кластер имеет небольшое количество узлов кластера и число секций по умолчанию будет небольшим, а запрос завершается сбоем или занимает длительное время выполнения.
Примечание.
Использование множества секций может использовать больше ресурсов кластера и снизить производительность. Тщательно выберите номер секции, начиная с hint.strategy = shuffle
и начиная постепенно увеличивать секции.
В некоторых случаях hint.strategy = shuffle
игнорируется запрос, и запрос не будет выполняться в shuffle
стратегии. Это может произойти в следующих случаях:
- Оператор
join
имеет другойshuffle
совместимый оператор (join
,summarize
make-series
илиpartition
) слева или справа. - Оператор
summarize
отображается после другогоshuffle
оператора, совместимого с совместимостью (join
илиsummarize
make-series
partition
) в запросе.
Синтаксис
С добавлением hint.strategy
= shuffle
T |
DataExpression DataExpression |
join
hint.strategy
= shuffle
(
)
T = |
summarize
hint.strategy
shuffle
DataExpression
Вложенный запрос T-секции hint.strategy
shuffle
(
= |
|
)
С hint.shufflekey
= помощью клавиши
T |
DataExpression key (
DataExpression |
join
hint.shufflekey
= )
T hint.shufflekey
summarize
= |
key DataExpression
T hint.shufflekey
make-series
= |
key DataExpression
Вложенный запрос ключа (
секции T |
= hint.shufflekey
|
)
Дополнительные сведения о соглашениях синтаксиса.
Параметры
Имя (название) | Type | Обязательно | Описание |
---|---|---|---|
T | string |
✔️ | Табличный источник, данные которого обрабатываются оператором. |
DataExpression | string |
Неявное или явное табличное выражение преобразования. | |
Запрос | string |
Выражение преобразования выполняется в записях T. | |
key | string |
join Используйте ключ, summarize ключ, make-series ключ или partition ключ. |
|
SubQuery | string |
Выражение преобразования. |
Примечание.
Необходимо указать dataExpression или Query в зависимости от выбранного синтаксиса.
Примеры
Использование суммы с перетасовкой
Запрос shuffle
стратегии с summarize
оператором разделяет нагрузку на все узлы кластера, где каждый узел обрабатывает одну секцию данных.
StormEvents
| summarize hint.strategy = shuffle count(), avg(InjuriesIndirect) by State
| count
Выходные данные
Count |
---|
67 |
Использование соединения с перетасовкой
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
Выходные данные
Count |
---|
103 |
Использование серии make с перетасовкой
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
Выходные данные
Штат | sum_DamageProperty | Время начала |
---|---|---|
СЕВЕРНАЯ ДАКОТА | [60000,0,0] | ["2006-12-31T00:00:00.000000Z","2007-01-15T00:00:0000:00.0000000Z","2007-01-30T00:00:00000000Z"] |
СЕВЕРНАЯ КАРОЛИНА | [20000,0,1000] | ["2006-12-31T00:00:00.000000Z","2007-01-15T00:00:0000:00.0000000Z","2007-01-30T00:00:00000000Z"] |
АТЛАНТИЧЕСКИЙ СЕВЕР | [0,0,0] | ["2006-12-31T00:00:00.000000Z","2007-01-15T00:00:0000:00.0000000Z","2007-01-30T00:00:00000000Z"] |
Использование секции с перетасовкой
StormEvents
| partition hint.strategy=shuffle by EpisodeId
(
top 3 by DamageProperty
| project EpisodeId, State, DamageProperty
)
| count
Выходные данные
Count |
---|
22345 |
Compare hint.strategy=shufflele and hint.shufflekey=key
При использовании hint.strategy=shuffle
оператор перетасовки будет перетасовыван всеми ключами. В следующем примере запрос перемешит данные с помощью обоих EpisodeId
и EventId
ключей:
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
Выходные данные
Count |
---|
14 |
В следующем запросе используется ключевое слово hint.shufflekey = key
. Приведенный выше запрос эквивалентен этому запросу.
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
Выходные данные
Count |
---|
14 |
Перемешив данные с несколькими ключами
В некоторых случаях hint.strategy=shuffle
запрос будет игнорироваться, и запрос не будет выполняться в стратегии перетасовки. Например, в следующем примере соединение содержит сводку в левой части, поэтому использование hint.strategy=shuffle
не будет применять стратегию перетасовки к запросу:
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
Выходные данные
EpisodeId | EventId | ... | EpisodeId1 | EventId1 | ... |
---|---|---|---|---|---|
1030 | 4407 | ... | 1030 | 4407 | ... |
1030 | 13721 | ... | 1030 | 13721 | ... |
2477 | 12530 | ... | 2477 | 12530 | ... |
2103 | 10237 | ... | 2103 | 10237 | ... |
2103 | 10239 | ... | 2103 | 10239 | ... |
... | ... | ... | ... | ... | ... |
Чтобы устранить эту проблему и запустить стратегию перетасовки, выберите ключ, который является общим для операций и join
операцийsummarize
. В этом случае этот ключ имеется EpisodeId
. Используйте указаниеhint.shufflekey
, чтобы указать ключ перетасовки для hint.shufflekey = EpisodeId
join
:
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
Выходные данные
EpisodeId | EventId | ... | EpisodeId1 | EventId1 | ... |
---|---|---|---|---|---|
1030 | 4407 | ... | 1030 | 4407 | ... |
1030 | 13721 | ... | 1030 | 13721 | ... |
2477 | 12530 | ... | 2477 | 12530 | ... |
2103 | 10237 | ... | 2103 | 10237 | ... |
2103 | 10239 | ... | 2103 | 10239 | ... |
... | ... | ... | ... | ... | ... |
Использование сводки с перетасовкой для повышения производительности
В этом примере использование summarize
оператора с shuffle
стратегией повышает производительность. Исходная таблица содержит 150 млн записей, а кратность группы по ключу — 10 млн, которая распространяется на 10 узлов кластера.
Использование summarize
оператора без shuffle
стратегии, запрос заканчивается после 1:08, а пик использования памяти составляет около 3 ГБ:
orders
| summarize arg_max(o_orderdate, o_totalprice) by o_custkey
| where o_totalprice < 1000
| count
Выходные данные
Count |
---|
1086 |
При использовании shuffle
стратегии summarize
с запросом заканчивается около 7 секунд, а пик использования памяти составляет 0,43 ГБ:
orders
| summarize hint.strategy = shuffle arg_max(o_orderdate, o_totalprice) by o_custkey
| where o_totalprice < 1000
| count
Выходные данные
Count |
---|
1086 |
В следующем примере показана производительность кластера с двумя узлами кластера с таблицей с 60 млн записей, где кратность группы по ключу составляет 2 млн.
Выполнение запроса без hint.num_partitions
использования только двух секций (в качестве номера узлов кластера) и следующий запрос займет около 1:10 минут:
lineitem
| summarize hint.strategy = shuffle dcount(l_comment), dcount(l_shipdate) by l_partkey
| consume
Если задать для секций значение 10, запрос завершится через 23 секунды:
lineitem
| summarize hint.strategy = shuffle hint.num_partitions = 10 dcount(l_comment), dcount(l_shipdate) by l_partkey
| consume
Использование соединения с перетасовкой для повышения производительности
В следующем примере показано, как использование shuffle
стратегии с оператором join
повышает производительность.
Примеры были приведены в кластере с 10 узлами, в которых данные распределяются по всем этим узлам.
Левая исходная таблица запроса содержит 15 млн записей, в которых кратность join
ключа составляет ~14M. Правый источник запроса содержит 150 млн записей, а кратность join
ключа — 10 МЛН. Запрос заканчивается через 28 секунд, а пик использования памяти составляет 1,43 ГБ:
customer
| join
orders
on $left.c_custkey == $right.o_custkey
| summarize sum(c_acctbal) by c_nationkey
При использовании shuffle
стратегии с оператором join
запрос заканчивается через 4 секунды, а пик использования памяти составляет 0,3 ГБ:
customer
| join
hint.strategy = shuffle orders
on $left.c_custkey == $right.o_custkey
| summarize sum(c_acctbal) by c_nationkey
В другом примере мы пытаемся выполнить те же запросы к большому набору данных со следующими условиями:
- Левый источник
join
составляет 150M, а кратность ключа — 148M. - Правый источник
join
составляет 1,5B, а кратность ключа составляет ~100M.
Запрос только с оператором join
попадает в ограничения и время ожидания после 4 минут. Однако при использовании shuffle
стратегии с оператором join
запрос заканчивается через 34 секунды, а пик использования памяти составляет 1,23 ГБ.
В следующем примере показано улучшение кластера с двумя узлами кластера с таблицей 60 млн записей, где кратность join
ключа составляет 2 млн.
Выполнение запроса без hint.num_partitions
использования только двух секций (в качестве номера узлов кластера) и следующий запрос займет около 1: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
При настройке числа секций значение 10 запрос завершится через 23 секунды:
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