쿼리 순서 섞기
쿼리는 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
연산자(join
,summarize
make-series
또는partition
)가 있습니다. - 연산자는
summarize
쿼리에서 호환되는 다른shuffle
연산자(join
,summarize
make-series
또는partition
) 다음에 나타납니다.
Syntax
With hint.strategy
= shuffle
T|
DataExpression|
join
hint.strategy
= shuffle
(
DataExpression)
T|
summarize
hint.strategy
= shuffle
DataExpression
T|
쿼리|
partition hint.strategy
(
= shuffle
SubQuery)
키와 함께 hint.shufflekey
=
T|
DataExpression|
join
hint.shufflekey
= 키(
DataExpression)
T|
summarize
hint.shufflekey
= keyDataExpression
T|
make-series
hint.shufflekey
= keyDataExpression
T|
쿼리|
파티션 hint.shufflekey
= 키(
SubQuery)
구문 규칙에 대해 자세히 알아보세요.
매개 변수
이름 | 형식 | 필수 | 설명 |
---|---|---|---|
T | string |
✔️ | 연산자가 데이터를 처리할 테이블 형식 원본입니다. |
DataExpression | string |
암시적 또는 명시적 테이블 형식 변환 식입니다. | |
쿼리 | string |
변환 식은 T의 레코드에서 실행됩니다. | |
key | string |
join 키, 키, summarize make-series 키 또는 partition 키를 사용합니다. |
|
하위 쿼리가 | string |
변환 식입니다. |
참고
선택한 구문에 따라 DataExpression 또는 쿼리 를 지정해야 합니다.
예제
순서 섞기를 사용하여 summarize 사용
연산자를 사용하는 summarize
전략 쿼리는 shuffle
각 노드가 데이터의 한 파티션을 처리하는 모든 클러스터 노드의 부하를 공유합니다.
StormEvents
| summarize hint.strategy = shuffle count(), avg(InjuriesIndirect) by State
| 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
출력
개수 |
---|
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
출력
시스템 상태 | 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
출력
개수 |
---|
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
출력
개수 |
---|
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
출력
개수 |
---|
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
사용하면 성능이 향상됩니다. 원본 테이블에는 150M 레코드가 있고 키별 그룹의 카디널리티는 10M이며 10개의 클러스터 노드에 걸쳐 있습니다.
전략 없이 shuffle
연산자를 사용하면 summarize
쿼리가 1:08 이후에 종료되고 메모리 사용량이 최대 3GB입니다.
orders
| summarize arg_max(o_orderdate, o_totalprice) by o_custkey
| where o_totalprice < 1000
| 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
출력
개수 |
---|
1086 |
다음 예제에서는 60M 레코드가 있는 테이블이 있는 두 개의 클러스터 노드가 있는 클러스터의 성능을 보여 줍니다. 여기서 키별 그룹의 카디널리티는 2M입니다.
없이 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
피드백
https://aka.ms/ContentUserFeedback
출시 예정: 2024년 내내 콘텐츠에 대한 피드백 메커니즘으로 GitHub 문제를 단계적으로 폐지하고 이를 새로운 피드백 시스템으로 바꿀 예정입니다. 자세한 내용은 다음을 참조하세요.다음에 대한 사용자 의견 제출 및 보기