GET_QUERY_OPERATOR_STATS¶
완료한 쿼리 내의 개별 쿼리 연산자에 대한 통계를 반환합니다. 지난 14일간 실행된 모든 완료된 쿼리에 대해 이 함수를 실행할 수 있습니다.
이 정보를 사용하여 쿼리 구조를 이해하고 성능 문제를 일으키는 쿼리 연산자(예: 조인 연산자)를 식별할 수 있습니다.
예를 들어 이 정보를 사용하여 가장 많은 리소스를 사용 중인 연산자를 확인할 수 있습니다. 또 다른 예로, 이 함수를 사용하여 입력 행보다 출력 행이 더 많은 조인을 식별할 수 있는데, 이는 “폭증하는” 조인 (예: 의도하지 않은 데카르트 곱)의 징후일 수 있습니다.
이러한 통계는 Snowsight 의 쿼리 프로필 탭에서도 사용할 수 있습니다. GET_QUERY_OPERATOR_STATS()
함수는 프로그래밍 방식의 인터페이스를 통해 동일한 정보를 제공합니다.
문제가 있는 쿼리 연산자를 찾는 방법에 대한 자세한 내용은 쿼리 프로필을 통해 확인된 일반 쿼리 문제 섹션을 참조하십시오.
구문¶
GET_QUERY_OPERATOR_STATS( <query_id> )
인자¶
query_id
쿼리의 ID입니다. 다음을 사용할 수 있습니다.
문자열 리터럴(작은따옴표로 묶인 문자열).
쿼리 ID를 포함하는 세션 변수.
LAST_QUERY_ID 함수에 대한 호출의 반환 값.
반환¶
GET_QUERY_OPERATOR_STATS 함수는 테이블 함수 입니다. 쿼리의 각 쿼리 연산자에 대한 통계가 포함된 행을 반환합니다. 자세한 내용은 아래의 사용법 노트 및 출력 섹션을 참조하십시오.
사용법 노트¶
이 함수는 완료된 쿼리에 대한 통계만 반환합니다.
쿼리를 실행한 웨어하우스에 대한 OPERATE 또는 MONITOR 권한이 있어야 합니다.
이 함수는 지정된 쿼리에 사용된 각 쿼리 연산자에 대한 자세한 통계를 제공합니다. 가능한 쿼리 연산자에는 다음이 포함됩니다.
Aggregate: 입력을 그룹화하고 집계 함수를 계산합니다.
CartesianJoin: 특수한 조인 유형.
Delete: 테이블에서 레코드를 제거합니다.
ExternalFunction: 외부 함수에 의한 처리를 나타냅니다.
ExternalScan: 스테이지 오브젝트에 저장된 데이터에 대한 액세스를 나타냅니다.
Filter: 행을 필터링하는 작업을 나타냅니다.
Flatten: VARIANT 레코드를 처리하여 지정된 경로에서 평면화할 수 있습니다.
Generator: TABLE(GENERATOR(…)) 구문을 사용하여 레코드를 생성합니다.
GroupingSets: GROUPING SETS, ROLLUP, CUBE 등의 구문을 나타냅니다.
Insert: INSERT 또는 COPY 작업을 통해 테이블에 레코드를 추가합니다.
InternalObject: 내부 데이터 오브젝트(예: Information Schema 또는 이전 쿼리 결과에서)에 대한 액세스를 나타냅니다.
Join: 지정된 조건에서 두 입력을 결합합니다.
JoinFilter: 쿼리 계획에서 더 이상 조인 조건과 일치하지 않는 것으로 식별될 수 있는 튜플을 제거하는 특수 필터링 작업입니다.
Merge: 테이블에 대한 MERGE 연산을 수행합니다.
Pivot: 열의 고유 값을 여러 열로 변환하고 필요한 집계를 수행합니다.
Result: 쿼리 결과를 반환합니다.
Sort: 지정된 식에서 입력을 정렬합니다.
SortWithLimit: 일반적으로
ORDER BY ... LIMIT ... OFFSET ...
구문의 결과인 정렬 후 입력 시퀀스의 일부를 생성합니다.TableScan: 단일 테이블에 대한 액세스를 나타냅니다.
UnionAll: 두 입력을 연결합니다.
Unload: 테이블의 데이터를 스테이지의 파일로 내보내는 COPY 작업을 나타냅니다.
Unpivot: 열을 행으로 변환하여 테이블을 회전합니다.
Update: 테이블에서 레코드를 업데이트합니다.
ValuesClause: VALUES 절과 함께 제공되는 값 목록입니다.
WindowFunction: 윈도우 함수를 계산합니다.
WithClause: SELECT 문의 본문에 선행하며 하나 이상의 CTE를 정의합니다.
WithReference: WITH 절의 인스턴스입니다.
이 정보는 테이블로 반환됩니다. 테이블의 각 행은 하나의 연산자에 해당합니다. 이 행에는 해당 연산자에 대한 실행 분석 및 쿼리 통계가 포함됩니다.
이 행에는 연산자 특성 도 나열될 수 있습니다(이러한 특성은 연산자 유형에 따라 다름).
쿼리 실행 시간을 분석한 통계는 전체 쿼리에서 사용한 시간의 백분율로 표현됩니다.
특정 통계에 대한 자세한 내용은 이 항목의 출력 섹션을 참조하십시오.
이 함수는 테이블 함수이므로 FROM 절에서 사용해야 하며
TABLE()
로 래핑해야 합니다. 예:select * from table(get_query_operator_stats(last_query_id()));
특정 쿼리(즉, 특정 UUID)의 각 개별 실행에 대해 이 함수는 결정적이며, 매번 똑같은 값을 반환합니다.
하지만 같은 쿼리 텍스트의 다른 실행에 대해 이 함수는 다른 런타임 통계를 반환할 수 있습니다. 통계는 많은 요인에 따라 달라집니다. 다음 요인은 실행에 중대한 영향을 미치며 따라서 이 함수에서 반환되는 통계에도 중대한 영향을 미칠 수 있습니다.
데이터의 양.
구체화된 뷰 의 가용성과 이러한 구체화된 뷰를 마지막으로 새로 고친 이후 데이터에 대한 변경 사항(있는 경우).
클러스터링 의 존재 또는 부재.
이전에 캐시된 데이터의 존재 또는 부재.
가상 웨어하우스의 크기.
값은 사용자의 쿼리와 데이터 외부 요인의 영향을 받을 수도 있습니다. 이러한 요인은 대개 작습니다. 이러한 요인에는 다음이 포함됩니다.
가상 웨어하우스 초기화 시간.
외부 함수 사용 시의 대기 시간.
출력¶
이 함수는 다음 열을 반환합니다.
열 이름 |
데이터 타입 |
설명 |
---|---|---|
QUERY_ID |
VARCHAR |
SQL 문에 대한 내부의 시스템 생성 식별자인 쿼리 ID. |
STEP_ID |
NUMBER(38, 0) |
쿼리 계획의 단계 식별자. |
OPERATOR_ID |
NUMBER(38, 0) |
연산자의 식별자. 이것은 쿼리 내에서 고유합니다. 값은 0에서 시작합니다. |
PARENT_OPERATORS |
하나 이상의 NUMBER를 포함한 ARRAY(38, 0) |
이 연산자에 대한 상위 연산자의 식별자, 또는 쿼리 계획의 마지막 연산자(보통은 Result 연산자)인 경우에는 NULL입니다. |
OPERATOR_TYPE |
VARCHAR |
쿼리 연산자의 유형(예: |
OBJECT를 포함하는 VARIANT |
연산자에 대한 통계(예: 연산자의 출력 행 수). |
|
OBJECT를 포함하는 VARIANT |
연산자의 실행 시간에 대한 정보. |
|
OBJECT를 포함하는 VARIANT |
연산자에 대한 정보. 이 정보는 연산자 유형에 따라 다릅니다. |
연산자의 특정 열에 대한 정보가 없는 경우 값은 NULL입니다.
이러한 열 중 세 개에 OBJECTs 가 포함됩니다. 각 오브젝트에는 키/값 페어가 있습니다. 아래 테이블에서는 이러한 테이블의 키에 대한 정보를 보여줍니다.
OPERATOR_STATISTICS¶
OPERATOR_STATISTICS
열의 OBJECTs에 있는 필드에서는 연산자에 대한 추가 정보를 제공합니다. 정보에는 다음이 포함될 수 있습니다.
키 |
중첩 키(해당되는 경우) |
데이터 타입 |
설명 |
---|---|---|---|
|
데이터 조작 언어(DML) 쿼리에 대한 통계: |
||
|
DOUBLE |
테이블 1개(또는 테이블 여러 개)에 삽입된 행 수. |
|
|
DOUBLE |
테이블에서 업데이트된 행 수. |
|
|
DOUBLE |
테이블에서 삭제된 행 수. |
|
|
DOUBLE |
데이터 내보내기 중 언로드된 행 수. |
|
|
외부 함수 호출에 대한 정보. 예를 들어 필드 |
||
|
DOUBLE |
외부 함수가 호출된 횟수. (행을 나누는 일괄 처리의 수, 재시도 횟수(일시적인 네트워크 장애가 있는 경우) 등으로 인해 SQL 문의 텍스트에 표시된 외부 함수 호출 횟수와 다를 수 있음) |
|
|
DOUBLE |
외부 함수로 전송된 행의 개수. |
|
|
DOUBLE |
외부 함수로부터 수신된 행의 개수. |
|
|
DOUBLE |
외부 함수로 전송된 행의 개수. 키에 |
|
|
DOUBLE |
외부 함수로부터 수신된 행의 개수. 키에 |
|
|
DOUBLE |
일시적인 오류로 인한 재시도 횟수. |
|
|
DOUBLE |
Snowflake가 데이터를 전송한 후 반환된 데이터를 수신한 시간 사이의 호출당 평균 시간(밀리초)입니다. |
|
|
INTEGER |
4xx 상태 코드를 반환한 총 HTTP 요청 수입니다. |
|
|
INTEGER |
5xx 상태 코드를 반환한 총 HTTP 요청 수입니다. |
|
|
DOUBLE |
성공적인 HTTP 요청을 위한 평균 대기 시간입니다. |
|
|
DOUBLE |
제한에 따른 속도 저하로 인한 성공적인 요청당 평균 오버헤드입니다(HTTP 429). |
|
|
DOUBLE |
HTTP 429 오류로 인해 재시도된 배치 수입니다. |
|
|
DOUBLE |
성공적인 HTTP 요청의 50번째 백분위수 대기 시간입니다. 성공적인 모든 요청의 50%가 완료하는 데 이 시간보다 짧게 걸렸습니다. |
|
|
DOUBLE |
성공적인 HTTP 요청의 90번째 백분위수 대기 시간입니다. 성공적인 모든 요청의 90%가 완료하는 데 이 시간보다 짧게 걸렸습니다. |
|
|
DOUBLE |
성공적인 HTTP 요청의 95번째 백분위수 대기 시간입니다. 성공적인 모든 요청의 95%가 완료하는 데 이 시간보다 짧게 걸렸습니다. |
|
|
DOUBLE |
성공적인 HTTP 요청의 99번째 백분위수 대기 시간입니다. 성공적인 모든 요청의 99%가 완료하는 데 이 시간보다 짧게 걸렸습니다. |
|
|
INTEGER |
입력 행 수. 이것은 다른 연산자의 입력 에지가 없는 연산자의 경우 누락될 수 있습니다. |
|
|
쿼리 중에 수행된 I/O(입출력) 작업에 대한 정보. |
||
|
DOUBLE |
해당 테이블에서 현재 스캔한 데이터의 백분율. |
|
|
DOUBLE |
현재까지 스캔한 바이트 수. |
|
|
DOUBLE |
로컬 디스크 캐시에서 스캔한 데이터의 백분율입니다. |
|
|
DOUBLE |
기록된 바이트 수(예: 테이블에 로드할 때). |
|
|
DOUBLE |
결과 오브젝트에 기록된 바이트 수. 예를 들어, 일반적으로, 결과의 결과로 생성된 모든 것을 나타내고 |
|
|
DOUBLE |
결과 오브젝트에서 읽은 바이트 수. |
|
|
DOUBLE |
외부 오브젝트(예: 스테이지)에서 읽은 바이트 수. |
|
|
|
DOUBLE |
네트워크를 통해 전송된 데이터의 양. |
|
INTEGER |
출력 행 수. 이것은 결과를 사용자에게 반환하는 연산자(보통 RESULT 연산자)의 경우 누락될 수 있습니다. |
|
|
테이블 잘라내기에 대한 정보. |
||
|
DOUBLE |
현재까지 스캔한 파티션의 수. |
|
|
DOUBLE |
지정된 테이블의 총 파티션 수. |
|
|
임시 결과가 메모리에 적합하지 않는 작업에 대한 디스크 사용량 정보. |
||
|
DOUBLE |
원격 디스크로 유출된 데이터의 볼륨. |
|
|
DOUBLE |
로컬 디스크로 유출된 데이터의 볼륨. |
|
|
확장 함수 호출에 대한 정보. 필드의 값이 0이면 필드가 표시되지 않습니다. |
||
|
DOUBLE |
로드할 Java UDF 처리기를 위한 시간입니다. |
|
|
DOUBLE |
Java UDF 처리기가 호출되는 횟수입니다. |
|
|
DOUBLE |
실행할 Java UDF 처리기의 최대 시간입니다. |
|
|
DOUBLE |
Java UDF 처리기를 실행할 평균 시간입니다. |
|
|
DOUBLE |
Java UDTF 프로세스 메서드 가 호출된 횟수입니다. |
|
|
DOUBLE |
Java UDTF 프로세스 실행에 걸리는 시간입니다. |
|
|
DOUBLE |
Java UDTF 프로세스 실행에 걸린 평균 시간입니다. |
|
|
DOUBLE |
Java UDTF 생성자 가 호출된 횟수입니다. |
|
|
DOUBLE |
Java UDTF 생성자 실행에 걸리는 시간입니다. |
|
|
DOUBLE |
Java UDTF 생성자 실행에 걸리는 평균 시간입니다. |
|
|
DOUBLE |
Java UDTF endPartition 메서드 가 호출된 횟수입니다. |
|
|
DOUBLE |
Java UDTF endPartition 메서드 실행에 걸리는 시간입니다. |
|
|
DOUBLE |
Java UDTF endPartition 메서드 실행에 걸리는 평균 시간입니다. |
|
|
DOUBLE |
Java UDF 종속 항목 다운로드에 걸리는 최대 시간입니다. |
|
|
DOUBLE |
JVM에서 보고한 최대 메모리 사용량입니다. |
|
|
DOUBLE |
Java UDF 인라인 코드의 컴파일 시간입니다. |
|
|
DOUBLE |
Python UDF 처리기가 호출된 횟수입니다. |
|
|
DOUBLE |
Python UDF 처리기의 총 실행 시간입니다. |
|
|
DOUBLE |
Python UDF 처리기 실행에 걸리는 평균 시간입니다. |
|
|
DOUBLE |
Python 샌드박스 환경의 최대 메모리 사용량입니다. |
|
|
DOUBLE |
패키지 다운로드와 설치를 포함하여 Python 환경을 만드는 데 걸리는 평균 시간입니다. |
|
|
DOUBLE |
Python 패키지를 해결하기 위해 Conda 솔버를 실행하는 데 걸리는 시간입니다. |
|
|
DOUBLE |
Python 환경을 만드는 데 걸리는 시간입니다. |
|
|
DOUBLE |
Python UDF를 초기화하는 데 걸리는 시간입니다. |
|
|
DOUBLE |
UDF에 대해 읽은 외부 파일 바이트 수입니다. |
|
|
DOUBLE |
UDF에 대해 액세스한 외부 파일 수입니다. |
EXECUTION_TIME_BREAKDOWN¶
EXECUTION_TIME_BREAKDOWN
열의 OBJECTs에 있는 필드가 아래에 나와 있습니다.
키 |
데이터 타입 |
설명 |
---|---|---|
|
DOUBLE |
이 연산자가 사용한 총 쿼리 시간의 백분율. |
|
DOUBLE |
쿼리 처리 설정에 사용한 시간. |
|
DOUBLE |
CPU에서 데이터를 처리하는 데 사용한 시간. |
|
DOUBLE |
참여 프로세스 간의 활동 동기화에 사용한 시간. |
|
DOUBLE |
로컬 디스크 액세스를 기다리는 동안 처리가 차단된 시간. |
|
DOUBLE |
원격 디스크 액세스를 기다리는 동안 처리가 차단된 시간. |
|
DOUBLE |
처리에서 네트워크 데이터 전송을 기다렸던 시간. |
OPERATOR_ATTRIBUTES¶
각 출력 행은 쿼리에서 한 연산자를 설명합니다. 아래 표에서는 가능한 연산자 유형(예: Filter 연산자)을 보여줍니다. 이 표에는 각 유형의 연산자에 대해 가능한 특성(예: 행을 필터링하는 데 사용되는 식)이 나와 있습니다.
연산자 특성은 VARIANT 형식이고 OBJECT 를 포함하는 OPERATOR_ATTRIBUTES
열에 저장됩니다. OBJECT는 키/값 페어를 포함합니다. 각각의 키는 연산자의 한 특성에 대응됩니다.
연산자 이름 |
키 |
데이터 타입 |
설명 |
---|---|---|---|
|
|||
|
VARCHAR로 구성된 ARRAY |
계산된 함수의 목록. |
|
|
VARCHAR로 구성된 ARRAY |
group-by 식. |
|
|
|||
|
VARCHAR |
같지 않음 조인 식. |
|
|
VARCHAR |
같음 조인 식. |
|
|
VARCHAR |
조인 타입(INNER). |
|
|
|
VARCHAR |
업데이트된 테이블의 이름. |
|
|||
|
VARCHAR |
데이터를 읽는 원본 스테이지의 이름. |
|
|
VARCHAR |
스테이지의 유형. |
|
|
|
VARCHAR |
데이터를 필터링하는 데 사용되는 식. |
|
|
VARCHAR |
데이터를 평면화하기 위해 사용되는 입력 식. |
|
|||
|
NUMBER |
입력 매개 변수 ROWCOUNT의 값. |
|
|
NUMBER |
입력 매개 변수 TIMELIMIT의 값. |
|
|
|||
|
VARCHAR로 구성된 ARRAY |
계산된 함수의 목록. |
|
|
VARCHAR로 구성된 ARRAY |
그룹화 세트의 목록. |
|
|
|||
|
VARCHAR |
삽입되는 식. |
|
|
VARCHAR로 구성된 ARRAY |
레코드가 추가된 테이블 이름의 목록. |
|
|
|
VARCHAR |
액세스한 오브젝트의 이름. |
|
|||
|
VARCHAR |
같지 않음 조인 식. |
|
|
VARCHAR |
같음 조인 식. |
|
|
VARCHAR |
조인 타입(INNER, OUTER, LEFT JOIN 등). |
|
|
|
NUMBER |
필터링할 수 있는 튜플을 식별하는 데 사용되는 조인의 연산자 ID. |
|
|
VARCHAR |
업데이트된 테이블의 이름. |
|
|||
|
VARCHAR로 구성된 ARRAY |
결과가 집계되는 나머지 열. |
|
|
VARCHAR로 구성된 ARRAY |
피벗 값의 결과 열. |
|
|
|
VARCHAR로 구성된 ARRAY |
생성된 식의 목록. |
|
|
VARCHAR로 구성된 ARRAY |
정렬 순서를 정의하는 식. |
|
|||
|
NUMBER |
생성된 튜플이 출력되는 순서가 지정된 시퀀스의 위치. |
|
|
NUMBER |
생성된 행의 개수. |
|
|
VARCHAR로 구성된 ARRAY |
정렬 순서를 정의하는 식. |
|
|
|||
|
VARCHAR로 구성된 ARRAY |
스캔된 열의 목록. |
|
|
VARCHAR로 구성된 ARRAY |
베리언트 열에서 추출된 경로의 목록. |
|
|
VARCHAR |
액세스 중인 테이블의 별칭. |
|
|
VARCHAR |
액세스 중인 테이블의 이름. |
|
|
|
VARCHAR |
데이터가 저장되는 스테이지. |
|
|
VARCHAR로 구성된 ARRAY |
피벗 해제 쿼리의 출력 열. |
|
|
VARCHAR |
업데이트된 테이블의 이름. |
|
|||
|
NUMBER |
생성된 값의 개수. |
|
|
VARCHAR |
값의 목록. |
|
|
|
VARCHAR로 구성된 ARRAY |
계산된 함수의 목록. |
|
|
VARCHAR |
WITH 절의 별칭입니다. |
연산자가 나열되지 않으면 아무런 특성도 생성되지 않고 값이 {}
으로 보고됩니다.
참고
다음 연산자에는 연산자 특성이 없으므로
OPERATOR_ATTRIBUTES
의 테이블 에 포함되지 않습니다.UnionAll
ExternalFunction
예¶
단일 쿼리에 대한 데이터 검색하기¶
이 예에서는 작은 테이블 두 개를 조인하는 SELECT의 통계를 보여줍니다.
SELECT 문을 실행합니다.
select x1.i, x2.i
from x1 inner join x2 on x2.i = x1.i
order by x1.i, x2.i;
쿼리 ID를 가져옵니다.
set lqid = (select last_query_id());
GET_QUERY_OPERATOR_STATS()를 호출하여 쿼리의 개별 쿼리 연산자에 대한 통계를 가져옵니다.
select * from table(get_query_operator_stats($lqid));
+--------------------------------------+---------+-------------+--------------------+---------------+-----------------------------------------+-----------------------------------------------+----------------------------------------------------------------------+
| QUERY_ID | STEP_ID | OPERATOR_ID | PARENT_OPERATORS | OPERATOR_TYPE | OPERATOR_STATISTICS | EXECUTION_TIME_BREAKDOWN | OPERATOR_ATTRIBUTES |
|--------------------------------------+---------+-------------+--------------------+---------------+-----------------------------------------+-----------------------------------------------+----------------------------------------------------------------------|
| 01a8f330-0507-3f5b-0000-43830248e09a | 1 | 0 | NULL | Result | { | { | { |
| | | | | | "input_rows": 64 | "overall_percentage": 0.000000000000000e+00 | "expressions": [ |
| | | | | | } | } | "X1.I", |
| | | | | | | | "X2.I" |
| | | | | | | | ] |
| | | | | | | | } |
| 01a8f330-0507-3f5b-0000-43830248e09a | 1 | 1 | [ 0 ] | Sort | { | { | { |
| | | | | | "input_rows": 64, | "overall_percentage": 0.000000000000000e+00 | "sort_keys": [ |
| | | | | | "output_rows": 64 | } | "X1.I ASC NULLS LAST", |
| | | | | | } | | "X2.I ASC NULLS LAST" |
| | | | | | | | ] |
| | | | | | | | } |
| 01a8f330-0507-3f5b-0000-43830248e09a | 1 | 2 | [ 1 ] | Join | { | { | { |
| | | | | | "input_rows": 128, | "overall_percentage": 0.000000000000000e+00 | "equality_join_condition": "(X2.I = X1.I)", |
| | | | | | "output_rows": 64 | } | "join_type": "INNER" |
| | | | | | } | | } |
| 01a8f330-0507-3f5b-0000-43830248e09a | 1 | 3 | [ 2 ] | TableScan | { | { | { |
| | | | | | "io": { | "overall_percentage": 0.000000000000000e+00 | "columns": [ |
| | | | | | "bytes_scanned": 1024, | } | "I" |
| | | | | | "percentage_scanned_from_cache": 1, | | ], |
| | | | | | "scan_progress": 1 | | "table_name": "MY_DB.MY_SCHEMA.X2" |
| | | | | | }, | | } |
| | | | | | "output_rows": 64, | | |
| | | | | | "pruning": { | | |
| | | | | | "partitions_scanned": 1, | | |
| | | | | | "partitions_total": 1 | | |
| | | | | | } | | |
| | | | | | } | | |
| 01a8f330-0507-3f5b-0000-43830248e09a | 1 | 4 | [ 2 ] | JoinFilter | { | { | { |
| | | | | | "input_rows": 64, | "overall_percentage": 0.000000000000000e+00 | "join_id": "2" |
| | | | | | "output_rows": 64 | } | } |
| | | | | | } | | |
| 01a8f330-0507-3f5b-0000-43830248e09a | 1 | 5 | [ 4 ] | TableScan | { | { | { |
| | | | | | "io": { | "overall_percentage": 0.000000000000000e+00 | "columns": [ |
| | | | | | "bytes_scanned": 1024, | } | "I" |
| | | | | | "percentage_scanned_from_cache": 1, | | ], |
| | | | | | "scan_progress": 1 | | "table_name": "MY_DB.MY_SCHEMA.X1" |
| | | | | | }, | | } |
| | | | | | "output_rows": 64, | | |
| | | | | | "pruning": { | | |
| | | | | | "partitions_scanned": 1, | | |
| | | | | | "partitions_total": 1 | | |
| | | | | | } | | |
| | | | | | } | | |
+--------------------------------------+---------+-------------+--------------------+---------------+-----------------------------------------+-----------------------------------------------+----------------------------------------------------------------------+
“폭증하는” 조인 연산자 식별하기¶
다음 예에서는 GET_QUERY_OPERATOR_STATS를 사용하여 복잡한 쿼리를 검사하는 방법을 보여줍니다. 이 예에서는 그 연산자에 입력된 것보다 훨씬 더 많은 행을 생성하는 쿼리 내에서 연산자를 찾습니다.
분석할 쿼리는 다음과 같습니다.
select *
from t1
join t2 on t1.a = t2.a
join t3 on t1.b = t3.b
join t4 on t1.c = t4.c
;
이전 쿼리의 쿼리 ID를 가져옵니다.
set lid = last_query_id();
다음 쿼리는 쿼리에서 각 조인 연산자의 입력 행에 대한 출력 행의 비율을 보여줍니다.
select
operator_id,
operator_attributes,
operator_statistics:output_rows / operator_statistics:input_rows as row_multiple
from table(get_query_operator_stats($lid))
where operator_type = 'Join'
order by step_id, operator_id;
+---------+-------------+--------------------------------------------------------------------------+---------------+
| STEP_ID | OPERATOR_ID | OPERATOR_ATTRIBUTES | ROW_MULTIPLE |
+---------+-------------+--------------------------------------------------------------------------+---------------+
| 1 | 1 | { "equality_join_condition": "(T4.C = T1.C)", "join_type": "INNER" } | 49.969249692 |
| 1 | 3 | { "equality_join_condition": "(T3.B = T1.B)", "join_type": "INNER" } | 116.071428571 |
| 1 | 5 | { "equality_join_condition": "(T2.A = T1.A)", "join_type": "INNER" } | 12.20657277 |
+---------+-------------+--------------------------------------------------------------------------+---------------+
폭증하는 조인을 식별한 후 각 조인 조건을 검토하여 조건이 올바른지 확인할 수 있습니다.