쿼리 프로필을 사용하여 쿼리 분석하기¶
Classic Console 를 통해 사용할 수 있는 쿼리 프로필은 쿼리에 대한 실행 세부 정보를 제공합니다. 그리고 선택한 쿼리에 대해 전체 쿼리에 대한 세부 정보 및 통계와 함께 각 구성 요소에 대한 통계 및 쿼리 처리 계획의 주요 구성 요소를 그래픽으로 보여줍니다.
이 항목의 내용:
소개¶
쿼리 프로필을 사용해야 하는 경우¶
쿼리 프로필은 쿼리의 역학을 이해할 수 있는 강력한 도구입니다. 특정 쿼리의 성능이나 동작에 대해 자세히 확인하기를 원하거나 그래야 할 때마다 사용할 수 있으며, 잠재적인 성능 병목 현상 및 향상 기회를 식별하기 위해 SQL 쿼리식에서 일반적인 실수를 확인할 수 있도록 설계되었습니다.
개별 쿼리에 대한 추가적인 정보는 Worksheets 및 History 페이지의 여러 열에서 확인할 수 있습니다.
쿼리 프로필에 액세스하는 방법¶
쿼리 프로필은 쿼리의 세부 정보 페이지에서 액세스할 수 있습니다. 그러므로 Query ID 열이 표시되고 쿼리 IDs를 클릭할 수 있는 모든 페이지에서 쿼리 프로필에 액세스할 수 있습니다.
참고
이러한 페이지에 Query ID 열이 표시되지 않으면 페이지의 열 머리글 중 1개의 옆에 있는 드롭다운을 클릭하고 Columns 목록에서 Query ID 를 선택합니다.
쿼리 프로필에 액세스하려면:
쿼리 프로필 인터페이스¶
이 항목의 목적을 위해 두 테이블을 조인하는 기본 샘플 SQL 쿼리를 사용하도록 하겠습니다.
select sum(j)
from x join y using (i)
where j > 300
and i < (select avg(j) from x);
다음 스크린샷은 이러한 쿼리에 대한 프로필을 보여줍니다.
인터페이스를 구성하는 주요 구성 요소는 다음과 같습니다.
- 단계:
쿼리가 여러 단계에서 처리되는 경우에는 각 단계 사이에서 전환할 수 있습니다.
- 연산자 트리:
중간 창에는 각 연산자 노드 사이의 관계 등 선택한 단계에 대한 모든 연산자 노드가 그래픽으로 표시됩니다.
- Node 목록:
가운데 창에는 실행 시간을 기준으로 축소 가능한 연산자의 노드 목록이 포함됩니다.
- 개요:
오른쪽 창에는 쿼리 프로필의 개요가 표시됩니다. 연산자 노드를 선택하면 디스플레이가 변경되어 연산자 세부 정보가 표시됩니다.
단계¶
쿼리는 여러 단계로 처리되는 경우가 많습니다. 예를 들어, 샘플 쿼리는 다음의 2개 단계로 처리됩니다.
1단계에서는
x.j
열의 평균을 계산합니다.2단계에서는 이러한 중간 결과를 사용하여 최종 쿼리 결과를 계산합니다.
쿼리 프로필은 각 처리 단계에서 별도의 패널에 표시됩니다. 각 단계를 클릭하여 패널 사이에서 전환할 수 있습니다. 샘플 쿼리의 경우, Step 2 를 클릭하면 뷰가 다음과 같이 변경됩니다.
연산자 트리¶
트리는 쿼리를 구성하는 연산자 노드와 각 연산자를 연결하는 링크에 대한 그래픽 표현을 제공합니다.
연산자는 쿼리의 기능적 구성 요소입니다. 그리고 데이터 액세스, 변환 및 업데이트 등 다양한 데이터 관리 및 처리 측면을 담당합니다. 트리의 각 연산자 노드에 포함되는 몇 가지 기본 속성은 다음과 같습니다.
- <타입> [#]:
연산자 타입 및 ID 번호입니다. ID를 사용하여 연산자 프로필 내에서 연사자를 고유하게 식별할 수 있습니다(예: 위 스크린샷의 Aggregate [5] 및 Join [11]).
전체 타입에 대한 설명은 아래 연산자 타입 을 참조하십시오.
- 백분율:
이 연산자가 각 쿼리 단계에서 사용하는 시간의 비율(예: Aggregate [5] 의 경우 25%)입니다. 이 정보는 연산자 노드 하단의 주황색 막대에도 표시되며 성능이 중요한 연산자를 시각적으로 편리하게 확인할 수 있습니다.
- 레이블:
연산자 고유의 추가 정보(예: Aggregate [5] 의 경우 SUM(X.J))입니다.
링크는 각 연산자 노드 사이에서 이동하는 데이터를 나타냅니다. 각 링크는 처리된 레코드 수(Join [11] 에서 Aggregate [5] 로 41.95M)를 제공합니다.
참고
터치 스크린을 사용하는데 연산자 트리가 표시되지 않으면 터치 스크린의 터치 이벤트 인터페이스가 간섭을 유발한 것일 수 있습니다. 인터페이스를 일시적으로 비활성화하는 지침은 Snowflake 커뮤니티 포럼에서 쿼리 프로필 윈도우에 개요가 표시되지만 쿼리 트리는 표시되지 않음 토론을 참조하십시오.
실행 시간별 연산자 노드¶
연산자 트리 창에서 축소가 가능한 패널은 실행 시간별로 노드를 내림차순으로 나열해, 사용자가 실행 시간의 측면에서 가장 비용이 많이 소요되는 연산자 노드를 빠르게 찾을 수 있습니다. 이 패널에는 쿼리의 총 실행 시간(또는 쿼리가 여러 처리 단계로 실행되는 경우 표시된 쿼리 단계의 실행 시간) 중 1% 이상 동안 유지된 모든 노드가 나열됩니다.
목록에서 노드를 클릭하면 해당 연산자 트리가 선택한 노드 중앙에 배치됩니다.
다음 스크린샷은 집계 [5] 연산자를 클릭한 이후의 패널을 보여줍니다.
프로필 개요/ 연산자 세부 정보¶
오른쪽의 개요/세부 정보 창은 왼쪽 트리에서 선택한 구성 요소(연산자 및 링크)에 대한 정보를 제공합니다. 표시되는 정보는 연산자 트리의 노드의 선택 여부에 따라 다릅니다.
처음에는 트리에서 노드가 선택되지 않으므로 현재 단계에 대한 개요 정보가 패널에 표시됩니다.
노드를 클릭하여 구성 요소를 선택하면 패널에 구성 요소에 대한 정보가 표시됩니다.
참고
노드를 클릭한 후 단계 수준 개요 정보로 돌아가려면 연산자 트리 주변의 빈 공간을 클릭해 노드의 선택을 해제하면 됩니다.
개요/세부 정보 창은 다음과 같은 3개의 섹션으로 나뉩니다.
- 실행 시간:
쿼리 시간을 소비한 처리 작업에 대한 정보를 제공합니다(아래 쿼리/연산자 세부 정보 참조). 또한, 단계 수준 정보와 관련하여 해당 단계의 상태와 실행 시간을 보여줍니다.
- 통계:
다양한 통계에 대한 자세한 정보를 제공합니다(아래 쿼리/연산자 세부 정보 참조).
- 속성:
구성 요소별 정보를 제공합니다(아래 연산자 타입 에서 설명 제공).
다음 스크린샷은 조인 [11] 연산자를 클릭한 이후의 세부 정보를 보여줍니다.
연산자 타입¶
다음 섹션에서는 가장 일반적인 연산자 타입의 목록 및 속성을 제공합니다.
데이터 액세스 및 생성 연산자¶
- TableScan:
단일 테이블에 대한 액세스를 나타냅니다. 속성:
전체 테이블 이름 — 데이터베이스 및 스키마를 포함하여 액세스한 테이블의 이름입니다.
열 — 스캔된 열 목록
테이블 별칭 — 사용된 테이블 별칭, 있는 경우
추출된 베리언트 경로 — VARIANT 열에서 추출된 경로의 목록
- ValuesClause:
VALUES 절과 함께 제공되는 값 목록입니다. 속성:
값의 개수 — 생성된 값의 개수입니다.
값 — 생성된 값의 목록입니다.
- 생성기:
TABLE(GENERATOR(...))
구문을 사용하여 레코드를 생성합니다. 속성:rowCount — 제공된 rowCount 매개 변수입니다.
timeLimit — 제공된 timeLimit 매개 변수입니다.
- ExternalScan:
스테이지 오브젝트에 저장된 데이터에 대한 액세스를 나타냅니다. 스테이지에서 직접 데이터를 스캔하는 쿼리의 일부일 수 있으며 데이터 로드 COPY 쿼리에서도 사용할 수 있습니다. 속성:
스테이지 이름 — 데이터를 읽는 스테이지의 이름입니다.
스테이지 타입 — 스테이지의 타입(예: TABLE STAGE)입니다.
- InternalObject:
내부 데이터 오브젝트(예: Information Schema 테이블 또는 이전 쿼리 결과)에 대한 액세스를 나타냅니다. 속성:
오브젝트 이름 — 액세스한 오브젝트의 이름 또는 타입입니다.
데이터 처리 연산자¶
- 필터:
레코드를 필터링하는 작업을 나타냅니다. 속성:
필터 조건 - 필터링을 수행하기 위해 사용되는 조건입니다.
- 조인:
지정된 조건에서 두 입력을 결합합니다. 속성:
조인 타입 — 조인 타입(예: INNER, LEFT OUTER 등)입니다.
같음 조인 조건 — 같음 기반 조건을 사용하는 조인의 경우 요소를 조인하기 위해 사용되는 식을 나열합니다.
추가 조인 조건 — 일부 조인은 같음이 아닌 조건자를 포함하는 조건을 사용합니다. 그러한 경우 여기에 나열됩니다.
참고
같음이 아닌 조인 조건자는 처리 속도가 상당히 느려질 수 있으므로 가능하면 사용하지 말아야 합니다.
- 집계:
입력을 그룹화하고 집계 함수를 계산합니다. GROUP BY 및 SELECT DISTINCT와 같은 SQL 구문을 나타낼 수 있습니다. 속성:
그룹화 키 — GROUP BY를 사용하면 그룹화 기준으로 사용된 식이 나열됩니다.
집계 함수 — 각 집계 그룹에 대해 계산된 함수(예: SUM)의 목록입니다.
- GroupingSets:
GROUPING SETS, ROLLUP 및 CUBE 등의 구문을 나타냅니다. 속성:
그룹화 키 세트 — 그룹화 세트의 목록
집계 함수 — 각 그룹에 대해 계산된 함수(예: SUM)의 목록입니다.
- WindowFunction:
윈도우 함수를 계산합니다. 속성:
윈도우 함수 — 계산된 윈도우 함수의 목록입니다.
- 정렬:
지정된 식에서 입력을 정렬합니다. 속성:
정렬 키 — 정렬 순서를 정의하는 식입니다.
- SortWithLimit:
일반적으로 SQL에서
ORDER BY ... LIMIT ... OFFSET ...
구문의 결과인 정렬 후 입력 시퀀스의 일부를 생성합니다. 속성:정렬 키 — 정렬 순서를 정의하는 식입니다.
행 개수 — 생성된 행의 개수입니다.
오프셋 — 생성된 튜플이 출력되는 순서가 지정된 시퀀스의 위치입니다.
- 데이터 스큐:
VARIANT 레코드를 처리하여 지정된 경로에서 평면화할 수 있습니다. 속성:
입력 — 데이터를 평면화하기 위해 사용되는 입력 식입니다.
- JoinFilter:
쿼리 계획에서 더 이상 조인 조건과 일치하지 않는 것으로 식별될 수 있는 튜플을 제거하는 특수 필터링 작업입니다. 속성:
원래 조인 ID — 필터링할 수 있는 튜플을 식별하기 위해 사용되는 조인입니다.
- UnionAll:
두 입력을 연결합니다. 속성: 없음
- ExternalFunction:
외부 함수에 의한 처리를 나타냅니다.
DML 연산자¶
- 삽입:
INSERT 또는 COPY 작업을 통해 테이블에 레코드를 추가합니다. 속성:
입력 식 — 식이 삽입됩니다.
전체 테이블 이름 — 레코드가 추가된 단일 대상 테이블의 이름입니다.
전체 테이블 이름 — 레코드가 추가된 여러 대상 테이블의 이름입니다.
- 삭제:
테이블에서 레코드를 제거합니다. 속성:
전체 테이블 이름 — 레코드가 삭제되는 테이블의 이름입니다.
- 업데이트:
테이블에서 레코드를 업데이트합니다. 속성:
전체 테이블 이름 — 업데이트된 테이블의 이름입니다.
- 병합:
테이블에 대한 MERGE 연산을 수행합니다. 속성:
전체 테이블 이름 — 업데이트된 테이블의 이름입니다.
- 언로드:
테이블의 데이터를 스테이지의 파일로 내보내는 COPY 작업을 나타냅니다. 속성:
위치 - 데이터가 저장되는 스테이지의 이름입니다.
메타데이터 연산자¶
일부 쿼리에는 데이터 처리 작업이 아닌 순수한 메타데이터/카탈로그 작업에 해당하는 단계가 포함됩니다. 이러한 단계는 단일 연산자로 구성됩니다. 몇 가지 예는 다음과 같습니다.
- DDL 및 트랜잭션 명령:
오브젝트, 세션, 트랜잭션 등을 생성 또는 수정하기 위해 사용됩니다. 일반적으로 이러한 쿼리는 가상 웨어하우스에 의해 처리되지 않으며 결과적으로 일치하는 SQL 문에 해당하는 단일 단계 프로필이 됩니다. 예:
CREATE DATABASE | SCHEMA | …
ALTER DATABASE | SCHEMA | TABLE | SESSION | …
DROP DATABASE | SCHEMA | TABLE | …
COMMIT
- 테이블 만들기 명령:
테이블을 만들기 위한 DDL 명령입니다. 예:
CREATE TABLE
다른 DDL 명령과 유사하게, 이러한 쿼리에서는 단일 단계 프로필이 생성되지만, CTAS 문에서 사용되는 경우와 같이 다단계 프로필의 일부일 수도 있습니다. 예:
CREATE TABLE … AS SELECT …
- 쿼리 결과 재사용:
이전 쿼리의 결과를 재사용하는 쿼리입니다.
- 메타데이터 기반 결과:
데이터에 액세스하지 않고 메타데이터만을 기반으로 하여 결과가 계산되는 쿼리입니다. 이러한 쿼리는 가상 웨어하우스에 의해 처리되지 않습니다. 예:
SELECT COUNT(*) FROM …
SELECT CURRENT_DATABASE()
기타 연산자¶
- 결과:
쿼리 결과를 반환합니다. 속성:
식 목록 - 생성된 식입니다.
쿼리/연산자 세부 정보¶
쿼리 성능 분석에 유용하게 사용할 수 있도록 세부 정보 패널은 다음 2가지 클래스의 프로파일링 정보를 제공합니다.
실행 시간, 카테고리별 분석
세부 통계
또한, 각 연산자에 대한 속성도 제공됩니다(이 항목의 연산자 타입 에서 설명 제공).
실행 시간¶
실행 시간은 쿼리를 처리하는 동안 “시간이 사용된 위치”에 대한 정보를 제공합니다. 사용한 시간은 다음의 카테고리로 분류하여 다음 순서로 표시될 수 있습니다.
Processing — CPU에서 데이터를 처리하기 위해 사용된 시간입니다.
Local Disk IO — 로컬 디스크 액세스에 의해 처리가 차단된 시간입니다.
Remote Disk IO — 원격 디스크 액세스에 의해 처리가 차단된 시간입니다.
Network Communication — 처리에서 네트워크 데이터 전송을 대기 중이었던 시간입니다.
Synchronization — 참여 프로세스 사이에서의 다양한 동기화 활동입니다.
Initialization — 쿼리 처리를 설정하기 위해 사용된 시간입니다.
통계¶
세부 정보 창에서 제공되는 주요 정보 소스는 다양한 통계이며, 이는 다음 섹션으로 그룹화됩니다.
IO — 쿼리 중에 수행된 입출력 작업에 대한 정보:
스캔 진행률 — 해당 테이블에서 현재 스캔한 데이터의 백분율입니다.
스캔된 바이트 수 — 현재까지 스캔한 바이트 수입니다.
캐시에서 스캔된 백분율 — 로컬 디스크 캐시에서 스캔한 데이터의 백분율입니다.
작성된 바이트 수 — 기록된 바이트 수(예: 테이블에 로드할 때)입니다.
결과에 작성된 바이트 수 — 결과 오브젝트에 기록된 바이트 수입니다. 예를 들어,
select * from . . .
은 선택 항목에 있는 각 필드를 나타내는 표 형식의 결과 세트를 생성합니다. 일반적으로, 결과의 결과로 생성된 모든 것을 나타내고 결과에 작성된 바이트 수 는 반환된 결과의 크기를 나타냅니다.결과에서 읽은 바이트 수 — 결과 오브젝트에서 읽은 바이트 수입니다.
스캔된 외부 바이트 수 — 외부 오브젝트(예: 스테이지)에서 읽은 바이트 수입니다.
DML — 데이터 조작 언어(DML) 쿼리에 대한 통계:
삽입된 행 수 — 테이블 1개(또는 테이블 여러 개)에 삽입된 행 수입니다.
업데이트된 행 수 — 테이블에서 업데이트된 행 수입니다.
삭제된 행 수 — 테이블에서 삭제된 행 수입니다.
언로드된 행 수 — 데이터 내보내기 중 언로드된 행 수입니다.
Pruning — 테이블 정리의 효과에 대한 정보:
스캔된 파티션 — 현재까지 스캔한 파티션의 수입니다.
파티션 총계 — 지정된 테이블의 총 파티션 수입니다.
Spilling — 임시 결과가 메모리에 적합하지 않는 작업에 대한 디스크 사용량 정보:
로컬 저장소로 분산된 바이트 수 —로컬 디스크에 분산된 데이터 볼륨입니다.
원격 저장소로 분산된 바이트 수 —원격 디스크에 분산된 데이터 볼륨입니다.
Network — 네트워크 통신:
네트워크를 통해 전송된 바이트 수 — 네트워크를 통해 전송된 데이터의 양입니다.
External Functions — 외부 함수 호출에 대한 정보:
SQL 문에 의해 호출되는 각 외부 함수와 관련하여 다음과 같은 통계가 표시됩니다. 동일한 SQL 문에서 동일한 함수가 두 번 이상 호출되면 통계가 집계됩니다.
총 호출 수 — 외부 함수가 호출된 횟수입니다. (행을 나누는 일괄 처리의 수, 재시도 횟수(일시적인 네트워크 장애가 있는 경우) 등으로 인해 SQL 문의 텍스트에 표시된 외부 함수 호출 횟수와 다를 수 있음)
전송된 행 수 — 외부 함수로 전송된 행의 개수입니다.
수신된 행 수 — 외부 함수로부터 수신된 행의 개수입니다.
전송된 바이트 수(x-리전) — 외부 함수로 전송된 행의 개수입니다. 레이블에 “(x-리전)”이 포함된 경우, 데이터가 여러 리전으로 전송되었습니다(청구에 영향을 줄 수 있음).
수신된 바이트 수(x-리전) — 외부 함수로부터 수신된 행의 개수입니다. 레이블에 “(x-리전)”이 포함된 경우, 데이터가 여러 리전으로 전송되었습니다(청구에 영향을 줄 수 있음).
일시적인 오류로 인한 재시도 — 일시적인 오류로 인한 재시도 횟수입니다.
호출당 평균 지연 시간 — Snowflake가 데이터를 전송한 후 반환된 데이터를 수신한 시간 사이의 호출당 평균 시간입니다.
HTTP 4xx 오류 — 4xx 상태 코드를 반환한 총 HTTP 요청 수입니다.
HTTP 5xx 오류 — 5xx 상태 코드를 반환한 총 HTTP 요청 수입니다.
성공한 호출당 대기 시간(평균) — 성공적인 HTTP 요청의 평균 대기 시간입니다.
평균 제한 대기 시간 오버헤드 — 제한에 따른 속도 저하로 인한 성공적인 요청당 평균 오버헤드입니다(HTTP 429).
제한으로 인해 재시도된 배치 — HTTP 429 오류로 인해 재시도된 배치 수입니다.
성공한 호출당 대기 시간(P50) — 성공적인 HTTP 요청의 50번째 백분위수 대기 시간입니다. 성공적인 모든 요청의 50%가 완료하는 데 이 시간보다 짧게 걸렸습니다.
성공한 호출당 대기 시간(P90) — 성공적인 HTTP 요청의 90번째 백분위수 대기 시간입니다. 성공적인 모든 요청의 90%가 완료하는 데 이 시간보다 짧게 걸렸습니다.
성공한 호출당 대기 시간(P95) — 성공적인 HTTP 요청의 95번째 백분위수 대기 시간입니다. 성공적인 모든 요청의 95%가 완료하는 데 이 시간보다 짧게 걸렸습니다.
성공한 호출당 대기 시간(P99) — 성공적인 HTTP 요청의 99번째 백분위수 대기 시간입니다. 성공적인 모든 요청의 99%가 완료하는 데 이 시간보다 짧게 걸렸습니다.
Extension Functions — 확장 함수 호출에 대한 정보:
Java UDF handler load time — 로드할 Java UDF 처리기를 위한 시간입니다.
Total Java UDF handler invocations — Java UDF 처리기가 호출되는 횟수입니다.
Max Java UDF handler execution time — 실행할 Java UDF 처리기의 최대 시간입니다.
Avg Java UDF handler execution time — Java UDF 처리기를 실행할 평균 시간입니다.
Java UDTF process() invocations — Java UDTF 프로세스 메서드 가 호출된 횟수입니다.
Java UDTF process() execution time — Java UDTF 프로세스 실행에 걸리는 시간입니다.
Avg Java UDTF process() execution time — Java UDTF 프로세스 실행에 걸린 평균 시간입니다.
Java UDTF’s constructor invocations — Java UDTF 생성자 가 호출된 횟수입니다.
Java UDTF’s constructor execution time — Java UDTF 생성자 실행에 걸리는 시간입니다.
Avg Java UDTF’s constructor execution time — Java UDTF 생성자 실행에 걸리는 평균 시간입니다.
Java UDTF endPartition() invocations — Java UDTF endPartition 메서드 가 호출된 횟수입니다.
Java UDTF endPartition() execution time — Java UDTF endPartition 메서드 실행에 걸리는 시간입니다.
Avg Java UDTF endPartition() execution time — Java UDTF endPartition 메서드 실행에 걸리는 평균 시간입니다.
Max Java UDF dependency download time — Java UDF 종속 항목 다운로드에 걸리는 최대 시간입니다.
Max JVM memory usage — JVM에서 보고한 최대 메모리 사용량입니다.
Java UDF inline code compile time in ms — Java UDF 인라인 코드의 컴파일 시간입니다.
Total Python UDF handler invocations — Python UDF 처리기가 호출된 횟수입니다.
Total Python UDF handler execution time — Python UDF 처리기의 총 실행 시간입니다.
Avg Python UDF handler execution time — Python UDF 처리기 실행에 걸리는 평균 시간입니다.
Python sandbox max memory usage — Python 샌드박스 환경의 최대 메모리 사용량입니다.
Avg Python env creation time: Download and install packages — 패키지 다운로드와 설치를 포함하여 Python 환경을 만드는 데 걸리는 평균 시간입니다.
Conda solver time — Python 패키지를 해결하기 위해 Conda 솔버를 실행하는 데 걸리는 시간입니다.
Conda env creation time — Python 환경을 만드는 데 걸리는 시간입니다.
Python UDF initialization time — Python UDF를 초기화하는 데 걸리는 시간입니다.
Number of external file bytes read for UDFs — UDF에 대해 읽은 외부 파일 바이트 수입니다.
Number of external files accessed for UDFs — UDF에 대해 액세스한 외부 파일 수입니다.
필드 값(예: “일시적인 오류로 인한 재시도”)이 0이면 필드가 표시되지 않습니다.
Snowflake Native App 의 쿼리 프로필에서 수정된 정보¶
Snowflake Native App Framework 는 다음과 같은 컨텍스트에서 쿼리 프로필 의 정보를 수정합니다.
앱이 설치되거나 업그레이드될 때 실행되는 쿼리입니다.
앱이 소유한 저장 프로시저에서 발생하는 쿼리입니다.
앱이 소유한 안전하지 않은 뷰 또는 함수가 포함된 쿼리입니다.
이러한 각 유형의 쿼리에 대해 Snowsight 는 전체 쿼리 프로필 트리를 표시하는 대신 쿼리 프로필 데이터를 비어 있는 단일 노드로 축소합니다.
쿼리 프로필을 통해 확인된 일반 쿼리 문제¶
이 섹션에서는 쿼리 프로필을 사용하여 식별 및 해결이 가능한 몇 가지 문제에 대해 설명합니다.
“급증하는” 조인¶
SQL 사용자가 저지르는 일반적인 실수 중 하나는 조인 조건을 제공하지 않고 테이블을 조인하거나(그로 인해 “데카르트 곱”이 수행됨) 한 테이블의 레코드가 다른 테이블의 여러 레코드와 일치하는 조건을 제공하는 것입니다. 이러한 쿼리의 경우 Join 연산자에서는 사용량보다 훨씬 더 많은 튜플을 생성(크기 기준)합니다.
이는 Join 연산자가 생성한 레코드의 수를 통해 확인할 수 있으며, 일반적으로 Join 연산자에서 오랜 시간이 걸리는 원인이 됩니다.
다음 예에서는 입력 레코드는 수백 개이지만 출력은 수십만 개인 경우를 보여줍니다.
SELECT tt1.c1, tt1.c2
FROM tt1
JOIN tt2 ON tt1.c1 = tt2.c1
AND tt1.c2 = tt2.c2;
ALL을 제외한 UNION¶
SQL에서는 UNION 또는 UNION ALL 구문으로 두 데이터 세트를 결합할 수 있습니다. 차이점은 UNION ALL는 단순히 입력을 연결하는 반면 UNION은 동일하게 연결하지만 중복 제거를 수행한다는 점입니다.
일반적인 실수는 UNION ALL 의미 체계로 충분한 상황에서 UNION를 사용하는 것입니다. 이러한 쿼리는 쿼리 프로필에 UnionAll 연산자로 표시되며 맨 위에는 추가 Aggregate 연산자(중복 제거 수행)가 표시됩니다.
너무 커서 메모리에 적합하지 않은 쿼리¶
일부 작업(예: 방대한 데이터 세트에 대한 중복 제거)의 경우 작업을 실행하기 위해 사용되는 컴퓨팅 리소스의 가용 메모리가 임시 결과를 유지하기에 충분하지 않을 수 있습니다. 결과적으로 쿼리 처리 엔진은 데이터를 로컬 디스크로 유출 하기 시작합니다. 로컬 디스크 공간이 충분하지 않으면 유출된 데이터가 원격 디스크에 저장됩니다.
이러한 유출은 쿼리 성능에 커다란 영향을 미칠 수 있습니다(특히 유출에서 원격 디스크가 사용되는 경우). 이를 완화하기 위한 권장 사항은 다음과 같습니다.
더 큰 크기의 웨어하우스 사용(사실상 작업에서 사용할 수 있는 메모리/로컬 디스크 공간을 증가) 및/또는
크기가 더 작은 일괄 처리로 데이터 처리.
비효율적인 정리¶
Snowflake는 데이터에 대한 풍부한 통계를 수집하여 쿼리 필터를 기반으로 테이블의 불필요한 부분을 읽을 필요가 없습니다. 그러나 이를 위해서는 데이터 저장소 순서가 쿼리 필터 속성과 관련이 있어야 합니다.
정리의 효율성은 TableScan 연산자에서 스캔된 파티션 및 전체 파티션 통계를 비교하여 확인할 수 있습니다. 전자가 후자에 비해 일부에 불과하면 정리가 효율적인 것입니다. 그렇지 않으면, 정리가 효과가 없는 것입니다.
물론, 정리는 실제로 상당한 양의 데이터를 필터링하는 쿼리에만 유용할 수 있습니다. 정리 통계에는 데이터 감소가 표시되지 않지만, 대량의 레코드를 필터링하는 TableScan 상단에 Filter 연산자가 있는 경우 다른 데이터 구성이 이 쿼리에 유용하다는 신호가 될 수 있습니다.
정리에 대한 자세한 내용은 Snowflake 테이블 구조 이해하기 을 참조하십시오.
Snowflake Native App 에서 수정된 쿼리 프로필 데이터¶
Snowflake Native App Framework 는 다음과 같은 컨텍스트에서 쿼리 프로필 의 정보를 수정합니다.
앱이 설치되거나 업그레이드될 때 실행되는 쿼리입니다.
앱이 소유한 저장 프로시저에서 발생하는 쿼리입니다.
앱이 소유한 안전하지 않은 뷰 또는 함수가 포함된 쿼리입니다.
이러한 각 유형의 쿼리에 대해 Snowsight 는 전체 쿼리 프로필 트리를 표시하는 대신 쿼리 프로필 데이터를 비어 있는 단일 노드로 축소합니다.