쿼리 순서 섞기
적용 대상: ✅Microsoft Fabric✅Azure Data Explorer✅Azure Monitor✅Microsoft Sentinel
쿼리는 shuffle
전략을 지원하는 shuffle
연산자 집합과 함께 사용되는 의미 체계 유지 변환입니다. 관련된 데이터에 따라 전략을 사용하여 쿼리하면 성능이 shuffle
향상될 수 있습니다. 키(join
키, 키, make-series
summarize
키 또는 partition
키)의 카디널리티가 높고 일반 연산자 쿼리가 쿼리 제한에 도달하면 순서 섞기 쿼리 전략을 shuffle
사용하는 것이 좋습니다.
순서 섞기 명령과 함께 다음 연산자를 사용할 수 있습니다.
쿼리 전략을 사용 shuffle
하려면 식을 hint.strategy = shuffle
추가하거나 hint.shufflekey = <key>
. 사용할 hint.strategy=shuffle
때 연산자 데이터는 모든 키에 의해 순서가 섞입니다. 복합 키가 고유하지만 각 키가 충분히 고유하지 않은 경우 이 식을 사용하므로 순서가 섞인 연산자의 모든 키를 사용하여 데이터를 섞습니다.
순서 섞기 전략으로 데이터를 분할하는 경우 데이터 로드는 모든 클러스터 노드에서 공유됩니다. 각 노드는 데이터의 하나의 파티션을 처리합니다. 기본 파티션 수는 클러스터 노드 수와 같습니다.
파티션 수를 제어하는 구문을 hint.num_partitions = total_partitions
사용하여 파티션 번호를 재정의할 수 있습니다. 클러스터에 적은 수의 클러스터 노드가 있고 기본 파티션 수가 적고 쿼리가 실패하거나 실행 시간이 오래 걸리는 경우에 유용합니다.
참고 항목
많은 파티션을 사용하면 더 많은 클러스터 리소스를 사용하고 성능을 저하시킬 수 있습니다. 파티션 번호부터 hint.strategy = shuffle
신중하게 선택하고 파티션을 점진적으로 늘리기 시작합니다.
경우에 따라 hint.strategy = shuffle
무시되고 쿼리가 전략에서 shuffle
실행되지 않습니다. 다음과 같은 경우에 이러한 문제가 발생할 수 있습니다.
- 연산자에는
join
왼쪽 또는 오른쪽에 호환되는 다른shuffle
연산자(make-series
join
summarize
또는partition
)가 있습니다. - 연산자는
summarize
쿼리에서 호환되는 다른shuffle
연산자(make-series
join
summarize
또는partition
) 뒤로 나타납니다.
구문
hint.strategy
= shuffle
사용
T |
DataExpressionhint.strategy
join
|
shuffle
(
= DataExpression )
T = |
summarize
hint.strategy
shuffle
DataExpression
T |
쿼리 |
파티션 = shuffle
(
hint.strategy
하위 쿼리 )
키와 함께 hint.shufflekey
=
T |
DataExpression = join
|
hint.shufflekey
키 (
DataExpression )
T hint.shufflekey
summarize
= |
키 DataExpression
T hint.shufflekey
make-series
= |
키 DataExpression
T |
쿼리 |
파티션 hint.shufflekey
= 키 (
SubQuery )
구문 규칙에 대해 자세히 알아봅니다.
매개 변수
이름 | Type | 필수 | 설명 |
---|---|---|---|
T | string |
✔️ | 연산자가 데이터를 처리할 테이블 형식 원본입니다. |
DataExpression | string |
암시적 또는 명시적 테이블 형식 변환 식입니다. | |
쿼리 | string |
변환 식은 T의 레코드에서 실행됩니다. | |
key | string |
join 키, 키, summarize make-series 키 또는 partition 키를 사용합니다. |
|
SubQuery | string |
변환 식입니다. |
참고 항목
선택한 구문에 따라 DataExpression 또는 쿼리를 지정해야 합니다.
예제
순서 섞기를 사용하여 요약 사용
연산자를 사용하는 summarize
전략 쿼리는 shuffle
각 노드가 데이터의 한 파티션을 처리하는 모든 클러스터 노드의 부하를 공유합니다.
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 |
순서 섞기에서 메이크 시리즈 사용
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
출력
State(상태) | sum_DamageProperty | StartTime |
---|---|---|
노스다코타주 | [60000,0,0] | ["2006-12-31T00:00:00.0000000Z","2007-01-15T00:00:00.0000000Z","2007-01-30T00:00:00.0000000Z"] |
노스캐롤라이나주 | [20000,0,1000] | ["2006-12-31T00:00:00.0000000Z","2007-01-15T00:00:00.0000000Z","2007-01-30T00:00:00.0000000Z"] |
대서양 북부 | [0,0,0] | ["2006-12-31T00:00:00.0000000Z","2007-01-15T00:00:00.0000000Z","2007-01-30T00:00:00.0000000Z"] |
순서 섞기에서 파티션 사용
StormEvents
| partition hint.strategy=shuffle by EpisodeId
(
top 3 by DamageProperty
| project EpisodeId, State, DamageProperty
)
| count
출력
Count |
---|
22345 |
hint.strategy=shuffle 및 hint.shufflekey=key 비교
사용할 hint.strategy=shuffle
때 순서 섞인 연산자는 모든 키에 의해 순서가 섞입니다. 다음 예제에서 쿼리는 키와 EventId
키를 모두 EpisodeId
사용하여 데이터를 순서를 섞습니다.
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
를 사용하여 다음의 순서 섞기 키를 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
출력
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
사용하면 성능이 향상됩니다. 원본 테이블에는 150M 레코드가 있고 키별 그룹의 카디널리티는 10M이며 10개 클러스터 노드에 걸쳐 있습니다.
전략 없이 shuffle
연산자를 사용하면 summarize
쿼리가 1:08 이후에 종료되고 메모리 사용량이 최대 3GB입니다.
orders
| summarize arg_max(o_orderdate, o_totalprice) by o_custkey
| where o_totalprice < 1000
| count
출력
Count |
---|
1086 |
전략을 summarize
사용하는 shuffle
동안 쿼리는 ~7초 후에 종료되고 메모리 사용량 최고는 0.43GB입니다.
orders
| summarize hint.strategy = shuffle arg_max(o_orderdate, o_totalprice) by o_custkey
| where o_totalprice < 1000
| count
출력
Count |
---|
1086 |
다음 예제에서는 키별 그룹의 카디널리티가 2M인 60M 레코드가 있는 테이블과 함께 두 개의 클러스터 노드가 있는 클러스터의 성능을 보여 줍니다.
쿼리를 실행하지 않고 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개의 노드가 있는 클러스터에서 샘플링되었습니다.
쿼리의 왼쪽 원본 테이블에는 키 카디널리티가 ~14M인 15M 레코드가 join
있습니다. 쿼리의 오른쪽 원본에는 150M 레코드가 있고 키의 join
카디널리티는 10M입니다. 쿼리는 최대 28초 후에 종료되고 메모리 사용량 최고는 1.43GB입니다.
customer
| join
orders
on $left.c_custkey == $right.o_custkey
| summarize sum(c_acctbal) by c_nationkey
연산자와 join
함께 전략을 사용하는 shuffle
경우 쿼리는 ~4초 후에 종료되고 메모리 사용량 최고는 0.3GB입니다.
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분 후 제한 및 시간 제한에 도달합니다. 그러나 연산자와 join
함께 전략을 사용하는 shuffle
경우 쿼리는 ~34초 후에 종료되고 메모리 사용량 최고는 1.23GB입니다.
다음 예제에서는 키의 카디널리티가 2M인 60M 레코드 테이블이 있는 두 개의 클러스터 노드가 있는 클러스터의 join
개선 사항을 보여 줍니다.
쿼리를 실행하지 않고 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