EXPLAIN 타입
AST— 추상 구문 트리입니다.SYNTAX— AST 수준 최적화가 적용된 후의 쿼리 텍스트입니다.QUERY TREE— 쿼리 트리 수준 최적화가 적용된 후의 쿼리 트리입니다.PLAN— 쿼리 실행 계획입니다.PIPELINE— 쿼리 실행 파이프라인입니다.ANALYZE— 쿼리를 실행하고 측정된 런타임 메트릭을 실행 계획에 덧붙입니다.ESTIMATE— 쿼리 처리 중 테이블에서 읽을 것으로 예상되는 행 수, 마크 수 및 파트 수입니다.TABLE OVERRIDE— 테이블 함수 스키마에 적용된 테이블 재정의의 유효성이 검증된 결과입니다.
EXPLAIN AST
SELECT뿐 아니라 모든 쿼리를 지원합니다.
설정:
graph– DOT 그래프 기술 언어로 표현된 그래프 형태로 AST를 출력합니다. 기본값: 0.
EXPLAIN 구문
oneline– 쿼리를 한 줄로 출력합니다. 기본값:0.run_query_tree_passes– 쿼리 트리를 덤프하기 전에 쿼리 트리 패스를 실행합니다. 기본값:0.query_tree_passes–run_query_tree_passes가 설정된 경우 실행할 패스 수를 지정합니다.query_tree_passes를 지정하지 않으면 모든 패스를 실행합니다.single_record– 줄마다 하나의 레코드를 반환하는 대신, 재포맷된 쿼리를 여러 줄로 구성된 단일 레코드로 반환합니다. 기본값은1이며(explain_syntax_single_record설정으로 제어됨),0으로 설정하면 기존의 줄당 하나의 레코드 출력 형식으로 복원됩니다. 또는explain_syntax_single_record = 0을 설정하거나(전역 또는 쿼리별SETTINGS에서),compatibility를26.8보다 이전 버전으로 설정하십시오.
Query
Response
run_query_tree_passes를 사용하는 경우:
Query
Response
EXPLAIN QUERY TREE
run_passes— 쿼리 트리를 덤프하기 전에 모든 쿼리 트리 패스를 실행합니다. 기본값:1.dump_passes— 쿼리 트리를 덤프하기 전에 사용된 패스 정보를 덤프합니다. 기본값:0.passes— 실행할 패스 수를 지정합니다.-1로 설정하면 모든 패스를 실행합니다. 기본값:-1.dump_tree— 쿼리 트리를 표시합니다. 기본값:1.dump_ast— 쿼리 트리에서 생성된 쿼리 AST를 표시합니다. 기본값:0.
EXPLAIN PLAN
optimize— 계획을 표시하기 전에 쿼리 계획 최적화를 적용할지 제어합니다. 기본값: 1.header— 단계의 출력 헤더를 출력합니다. 기본값: 0.description— 단계 설명을 출력합니다. 기본값: 1.indexes— 사용된 인덱스와, 적용된 각 인덱스별로 필터링된 파트 수 및 필터링된 그래뉼 수를 표시합니다. 기본값: 0. MergeTree 테이블에서 지원됩니다. ClickHouse >= v25.9부터는 이 문을SETTINGS use_query_condition_cache = 0, use_skip_indexes_on_data_read = 0와 함께 사용할 때만 출력이 적절하게 표시됩니다.projections— 분석된 모든 프로젝션과, 프로젝션 프라이머리 키 조건에 기반한 파트 수준 필터링에 미치는 영향을 표시합니다. 각 프로젝션에 대해 이 섹션에는 프로젝션의 프라이머리 키를 사용해 평가된 파트 수, 행 수, 마크 수, 범위 수 등의 통계가 포함됩니다. 또한 프로젝션 자체를 읽지 않고도 이 필터링으로 인해 건너뛴 데이터 파트 수를 보여줍니다. 프로젝션이 실제 읽기에 사용되었는지, 아니면 필터링용으로만 분석되었는지는description필드로 확인할 수 있습니다. 기본값: 0. MergeTree 테이블에서 지원됩니다.actions— 단계 작업에 대한 자세한 정보를 출력합니다. 기본값: 1.sorting— 정렬된 출력을 생성하는 각 계획 단계의 정렬 설명을 출력합니다. 기본값: 0.keep_logical_steps— 조인을 물리적 조인 구현으로 변환하지 않고 논리적 계획 단계를 유지합니다. 기본값: 0.json— 쿼리 계획 단계를 JSON 포맷의 한 행으로 출력합니다. 기본값: 0. 불필요한 이스케이프를 피하려면 TabSeparatedRaw (TSVRaw) 포맷을 사용하는 것이 좋습니다.input_headers— 단계의 입력 헤더를 출력합니다. 기본값: 0. 주로 입력-출력 헤더 불일치와 관련된 문제를 디버깅하는 개발자에게만 유용합니다.column_structure— 헤더에서 컬럼의 이름과 유형뿐 아니라 구조도 함께 출력합니다. 기본값: 0. 주로 입력-출력 헤더 불일치와 관련된 문제를 디버깅하는 개발자에게만 유용합니다.distributed— 분산 테이블 또는 병렬 레플리카의 원격 노드에서 실행되는 쿼리 계획을 표시합니다.json과 함께는 지원되지 않습니다. 기본값: 0.compact— 활성화하면 계획에서 표현식 단계와 자세한 작업 정보(입력, 함수, aliases, 출력 위치)를 숨깁니다.actions = 1일 때만 효과가 있습니다. 기본값: 1.pretty— 들여쓰기 대신 선 그리기 문자(├──, └──, │)를 사용해 계층 구조를 시각화한 계획 트리를 출력합니다. 또한 조인 단계 속성을 인라인으로 포맷합니다. 기본값: 1.
기본적으로
explain_query_plan_default = 'pretty'이므로 actions, compact, pretty는 1로 초기화되며 계획은 compact, pretty, action 주석이 포함된 형태로 렌더링됩니다. EXPLAIN 문에서 이러한 옵션 중 하나를 명시적으로 지정하면(예: EXPLAIN actions = 0, compact = 0, pretty = 0 SELECT ...) 항상 기본값을 재정의합니다.ClickHouse 26.7 이전에는 actions, compact, pretty의 기본값이 0이었습니다. explain_query_plan_default = 'legacy'로 설정하거나(전역 또는 쿼리별 SETTINGS에서), compatibility를 26.7보다 이전 버전으로 설정하면 여전히 해당 출력을 얻을 수 있습니다.json 및 distributed 옵션은 explain_query_plan_default = 'pretty'인 경우에도 pretty 기본값(actions, compact, pretty)을 활성화하지 않습니다. 해당 출력에 action 세부 정보를 포함하려면 actions = 1을 수동으로 설정하십시오.단계별 비용 및 쿼리 비용 추정은 지원되지 않습니다.
json = 1이면 쿼리 계획이 JSON 포맷으로 표시됩니다. 모든 노드는 항상 Node Type, Node Id, Plans 키를 가지는 딕셔너리입니다. Node Type은 단계 이름을 나타내는 문자열이고, Node Id는 고유한 단계 식별자입니다(숫자 접미사가 붙은 단계 이름으로, 예: Union_10). Plans는 하위 단계 설명을 담은 배열입니다. 그 밖의 선택적 키는 노드 유형과 설정에 따라 추가될 수 있습니다.
예시:
description = 1이면 Description 키가 해당 단계에 추가됩니다:
header = 1이면 Header 키가 컬럼 배열 형태로 해당 단계에 추가됩니다.
예시:
indexes = 1이면 Indexes 키가 추가됩니다. 이 키에는 사용된 인덱스의 배열이 포함됩니다. 각 인덱스는 Type 키(문자열 Partition Min-Max, Partition, Statistics, PrimaryKey 또는 Skip)와 선택적 키를 포함하는 JSON으로 설명됩니다.
Name— 인덱스 이름입니다(현재는Skip인덱스에만 사용됩니다).Keys— 인덱스에 사용되는 컬럼 배열입니다.Condition— 사용된 조건입니다.Description— 인덱스 설명입니다(현재는Skip인덱스에만 사용됩니다).Parts— 인덱스 적용 전/후의 파트 수입니다.Granules— 인덱스 적용 전/후의 그래뉼 수입니다.Ranges— 인덱스 적용 후의 그래뉼 범위 수입니다.
projections = 1로 설정하면 Projections 키가 추가됩니다. 이 키에는 분석된 프로젝션의 배열이 포함됩니다. 각 프로젝션은 다음 키를 포함하는 JSON으로 설명됩니다:
Name— 프로젝션 이름입니다.Condition— 사용된 프로젝션 프라이머리 키 조건입니다.Description— 프로젝션이 어떻게 사용되는지에 대한 설명입니다(예: 파트 수준 필터링).Selected Parts— 프로젝션이 선택한 파트 수입니다.Selected Marks— 선택된 마크 수입니다.Selected Ranges— 선택된 범위 수입니다.Selected Rows— 선택된 행 수입니다.Filtered Parts— 파트 수준 필터링으로 건너뛴 파트 수입니다.
actions = 1로 설정하면, 추가되는 키는 단계 유형에 따라 달라집니다.
예시:
compact = 0과 actions = 1을 설정하면 Expression 단계와 함께 표현식에 대한 상세 정보를 확인할 수 있습니다:
distributed = 1로 설정하면 로컬 쿼리 플랜뿐만 아니라 원격 노드에서 실행될 쿼리 플랜도 출력에 포함됩니다. 분산 쿼리를 분석하고 디버깅할 때 유용합니다.
distributed는 pretty 출력이 원격 세그먼트의 계획을 계획 트리에 통합하지 않기 때문에 레거시(pretty가 아닌) 형식으로만 표시됩니다. 이러한 이유로 distributed를 활성화하면 explain_query_plan_default와 관계없이 pretty 기본값(actions, compact, pretty)이 자동으로 비활성화됩니다. 그래도 actions=1은 수동으로 설정할 수 있습니다. 또한 distributed 옵션은 json과 함께 사용할 수 없습니다.pretty = 1로 설정하면 들여쓰기 대신 선 그리기 문자를 사용하여 플랜 트리가 표시되며, 주요 단계에 대한 추가 정보도 함께 표시됩니다:
- 쿼리 출력 컬럼은 플랜 상단에 표시됩니다.
- 필터, 집계 키, 정렬 설명, 윈도우 함수의 표현식은 사람이 읽기 쉬운 SQL 유사 표기법으로 표시됩니다(예:
greater(plus(a, 1), 5)대신a + 1 > 5). 명확성을 위해 내부 컬럼 식별자 프리픽스(예:__table1.)는 제거됩니다. - 소스 단계(
ReadFromMergeTree등)는 출력 컬럼을 표시합니다. - 필터 단계는 필터 조건을 SQL 표기법으로 표시합니다. 런타임 조인 필터가 있는 경우 별도로 표시됩니다.
- 집계 단계는 키와 해당 인수가 포함된 집계 함수를 표시합니다(예:
sum(c),count()). - 튜플 리터럴의 IN Set은 값을 표시하며(큰 Set의 경우 잘림), 서브쿼리 기반 Set에는
subquery1,subquery2등의 레이블이 지정되고,Set엔진 테이블의 Set은 테이블 이름을 표시합니다. - 조인 단계는 수학적 표기법을 사용한 조인 릴레이션, 예상 결과 행 수, 그리고 어떤 출력 컬럼이 왼쪽과 오른쪽에서 오는지를 표시합니다. 다음 기호는 서로 다른 JOIN 유형을 나타내는 데 사용됩니다:
예를 들어,
t1 ⟕ t2는 테이블 t1과 t2 사이의 왼쪽 조인을 의미합니다.
테이블 이름 뒤 대괄호 안의 숫자(예: t1[100])는 예상 행 수를 나타내며,
테이블 통계를 사용할 수 있을 때 표시됩니다.
pretty 옵션은 compact = 1과 함께 사용하면 효과적이며, 이 경우 Expression 단계와 자세한 작업 정보가 숨겨져 계획을 더 읽기 쉽게 만듭니다.
조인을 사용하는 더 자세한 예시:
EXPLAIN PIPELINE
header— 각 출력 포트의 헤더를 출력합니다. 기본값: 0입니다.graph— DOT 그래프 기술 언어로 작성된 그래프를 출력합니다. 기본값: 0입니다.compact—graph설정이 활성화되면 그래프를 compact 모드로 출력합니다. 기본값: 1입니다.compact_repeated_processor_chains— 텍스트 출력에서 인접하게 반복되는 프로세서 체인을, 반복 횟수와 함께 체인 하나만 표시하는 방식으로 압축합니다. 예를 들어 조인에서 동일한 체인이 여러 번 나타나는 경우 병렬 파이프라인을 더 쉽게 읽을 수 있습니다. 그래프 출력에는 영향을 주지 않습니다. 기본값: 0입니다.
compact=0이고 graph=1이면 프로세서 이름에 고유한 프로세서 식별자를 나타내는 추가 접미사가 포함됩니다.
예시:
EXPLAIN ANALYZE
EXPLAIN ANALYZE는 실제로 쿼리를 실행하고 결과 행은 버린 다음, 각 단계에 실행 시 실제로 발생한 내용을 표시하여 EXPLAIN PLAN과 동일한 계획 트리를 출력합니다.
설정:
EXPLAIN ANALYZE는 EXPLAIN PLAN과 동일한 표시 옵션을 지원합니다(EXPLAIN PLAN 섹션에 설명되어 있음).
header— EXPLAIN PLAN 섹션을 참조하십시오.description— EXPLAIN PLAN 섹션을 참조하십시오.projections— EXPLAIN PLAN 섹션을 참조하십시오.sorting— EXPLAIN PLAN 섹션을 참조하십시오.input_headers— EXPLAIN PLAN 섹션을 참조하십시오.column_structure— EXPLAIN PLAN 섹션을 참조하십시오.actions— EXPLAIN PLAN 섹션을 참조하십시오. 기본값: 1.indexes— EXPLAIN PLAN 섹션을 참조하십시오. 기본값: 1.compact— EXPLAIN PLAN 섹션을 참조하십시오. 기본값: 1.pretty— EXPLAIN PLAN 섹션을 참조하십시오. 기본값: 1.processors—EXPLAIN ANALYZE에서는 각 스테이지마다 프로세서별 경과 시간 분포(min,median,max,sum)를 보여주는 추가 줄을 출력합니다. 병렬 프로세서 간 부하 편차를 파악하는 데 유용합니다. 기본값: 0.matches—EXPLAIN ANALYZE에서는 조인 결과만으로 해당 수치를 도출할 수 없는 경우matched,match rate,fanout메트릭에 필요한 추가 기록 작업을 조인 단계에서 수행합니다. 도출할 수 있는 경우에는 이 옵션 없이도 보고됩니다. 조인 단계를 참조하십시오. 기본값: 0.
EXPLAIN ANALYZE는 감싼 쿼리를 실제로 실행하므로, 여러 측면에서
실행하지 않는 EXPLAIN 형식과는 달리 해당 쿼리와 동일하게 동작합니다:- 쿼터와 제한. 직접 쿼리를 실행할 때와 동일한 쿼터가 적용되며,
동일한 제한
(예:
query_selects,read_rows)의 적용을 받습니다. 계획 수립 중 쿼터가 면제되는 소스 (예:system.one)에는 과금되지 않습니다. - 실패한 트랜잭션. 이미 실패한(
ROLLED_BACK) 트랜잭션 내부에서는 일반SELECT와 마찬가지로INVALID_TRANSACTION과 함께 거부되므로, 먼저ROLLBACK을 실행하십시오. - 스트리밍 읽기. 스트리밍(
FROM ... STREAM) 읽기에서는 해당 읽기가 끝나지 않기 때문에NOT_IMPLEMENTED와 함께 거부됩니다. - 분산 쿼리. 분산 모드에서 실행되는 쿼리에는 지원되지 않습니다.
Time— 총 시간이며, 계획 단계(즉, 계획 생성 + 계획 최적화 + 파이프라인 구성)와 실행 단계(파이프라인 실행)로 나뉩니다.Read— 테이블에서 읽은 행 수와 비압축 바이트 수이며, 처리량이 함께 표시됩니다. 이는 일반 쿼리 footer에 “Processed”로 표시되는 것과 동일한 수치입니다.Peak memory— 쿼리가 사용한 최대 메모리입니다.
I/O 줄). 시간과 병렬성은 간격의 각 스테이지별로 다음 들여쓴 줄에 표시됩니다.
rows <in> → <out>— 간격에 들어온 행 수와 간격을 빠져나간 행 수입니다. (<selectivity>%)는 간격이 데이터를 얼마나 필터링했는지(out/in) 또는 확장했는지를 보여주며, 입력 행 수와 출력 행 수가 같거나 입력 행 수가0일 때는 표시되지 않습니다.<bytes_in> → <bytes_out>— 간격을 통과하는 비압축 인메모리 바이트 수입니다(둘 다 0이면 생략됨).time <t> (<share>%)— 해당 스테이지가 활성 상태였던 실제 경과 시간(wall-clock time)과 쿼리 실행 시간에서 차지하는 비율입니다(즉, build 시간 제외). 스테이지와 간격은 동시에 실행될 수 있으므로 비율의 합이 100%를 초과할 수 있습니다.parallelism <avg>/<max>— 이 스테이지 내에서 동시에 작업한 CPU 스레드의 평균 수와, 사용할 수 있었던 최대 수입니다. 값이 최대치에 가까우면 해당 스테이지가 잘 병렬화되었음을 의미하고, 1에 가까우면 대부분 직렬로 실행되었음을 의미합니다.Stage (<stage>)— 스테이지의 이름입니다. 스테이지가 하나뿐인 간격은Stage (...)레이블 없이 시간 줄을 직접 출력합니다. 여러 스테이지가 있는 간격은 스테이지마다 레이블이 붙은 줄을 하나씩 출력합니다. 예를 들어Aggregating은Stage (partial aggregation)과Stage (final aggregation)을 표시하고, 해시 조인은Stage (build)와Stage (probe)를 표시합니다.
ClickHouse는 계획 단계 내 작업의 실행뿐 아니라 계획 단계 자체의 실행도 병렬화합니다.
parallelism 메트릭은 이 간격의 작업만 반영합니다. 다른 간격도 동시에 실행될 수 있으므로, 이 수치만으로는 해당 간격의 병렬성이 전체 쿼리와 비교해 어느 정도인지는 알 수 없습니다.parallelism의 최대값은 다음 두 값 중 최솟값으로 계산됩니다.- 계획 단계 내 전체 작업 수
max_threads에 설정된 최대 쿼리 처리 스레드 수
조인 단계
EXPLAIN ANALYZE는 각 측의 참여 행인 Left와 Right를 출력한 후, 조인 구현에 특화된 행을 출력합니다. Left와 Right는 논리적인 SQL 측면에 해당합니다. 대부분 Left는 조인의 프로브 측이고 Right는 빌드 측이지만, 조인 실행 중 스왑이 발생할 수 있으므로 항상 그렇지는 않습니다. join_algorithm의 모든 값(hash, parallel_hash, grace_hash, partial_merge, full_sorting_merge, parallel_full_sorting_merge, direct)이 지원됩니다. 또한 이 설정으로 선택할 수 없는 두 구현, 즉 CROSS 또는 COMMA 조인, 키 동등 조건이 없는 모든 ON 절 및 Join 테이블 엔진도 지원됩니다. 대부분은 양쪽 모두에 대한 정보를 보고하지만, 일부는 구체화하는 측에 대해서만 보고합니다(예: direct는 Left:만 출력합니다).
각 측의 행은 동일한 형식을 따릅니다:
EXPLAIN ANALYZE는 다음을 보고합니다.
rows <rows>— 해당 측면에서 조인을 거친 전체 행 수입니다.matched <matched_rows>— 반대 측면에서 하나 이상의 조인 파트너와 일치한 해당 측면의 행 수입니다. 키가 아닌 행을 계산합니다. 예를 들어 키가 오른쪽에 세 번 나타나 일치하는 경우, 오른쪽의 세 행 모두 일치한 것으로 계산됩니다.match rate <match_rate>%— 해당 측면에서 일치한 행의 비율이며,100 * <matched_rows> / <rows>로 계산됩니다.fanout <fanout>— 해당 측면에서 일치한 행 하나당 평균적으로 생성된 출력 행 수입니다.
0이 아니라 not collected로 보고됩니다. match rate와 fanout은 matched에서 산출되므로, matched가 없는 측면에서는 세 항목 모두 not collected로 보고됩니다.
팬아웃
fanout은 행이 얼마나 늘어나는지를 측정합니다:
NULL로 채워진 출력 행을 하나 생성합니다. 이러한 행은 비율을 왜곡하지 않도록 제외합니다. 이러한 행은 보존 측에만 존재합니다. 즉, RIGHT 및 FULL에서는 오른쪽 측에, LEFT 및 FULL에서는 왼쪽 측에 존재합니다.
fanout = 0— 일치한 행이 출력 행을 전혀 생성하지 않았습니다. 이는ANTI조인의 동작으로, 상대 행을 찾지 못한 행만 출력합니다.fanout = 1— 깔끔한 1:1 조인으로, 일치한 각 행이 정확히 하나의 출력 행을 생성했습니다.fanout > 1— 1:N 조인으로, 반대쪽의 중복 key로 인해 행 수가 늘어났습니다. 양쪽에서 동시에 큰 값이 나타나면 의도하지 않은 데카르트 곱 폭증의 징후입니다.
수치에 matches = 1이 필요한 경우
EXPLAIN ANALYZE로 보고됩니다. 나머지는 조인이 그렇지 않으면 수행하지 않을 추가 기록 작업이 필요하므로 EXPLAIN ANALYZE matches = 1에서만 보고됩니다. 어떤 수치가 이에 해당하는지는 알고리즘에 따라 달라지며, 해시 계열에서는 다음 두 가지입니다.
- 일치하는 모든 오른쪽 행을 표시해야 하는
ALL INNER및ALL LEFT의 오른쪽 - 쿼리가 오른쪽 테이블에서 아무것도 선택하지 않고
ON절이 단순한 키 동등 조건인 경우에만 해당하는ALL LEFT및ALL FULL의 왼쪽. 그렇지 않으면 프로브에서 이미 어떤 왼쪽 행이 일치했는지 기록합니다. 이는 오른쪽 컬럼을 구체화하거나 잔여 조건을 평가하기 위해 필요하므로, 옵션 없이도 개수가 정확합니다.
partial_merge는 같은 이유로 네 가지 ALL 유형의 오른쪽에 이를 필요로 합니다.
full_sorting_merge와 parallel_full_sorting_merge는 ANY 유형의 양쪽에 이를 필요로 합니다. ALL
유형에는 아무것도 필요하지 않습니다.
추가 기록 작업은 비용이 발생하므로 이 옵션은 기본적으로 꺼져 있으며, 이는 측정 정확도를 위해 치르는 비용입니다. 작업은 프로브 루프 내에서 수행되며 출력 행 수에 따라 증가합니다. 왼쪽 및 오른쪽 행이 반대편에서 찾은 정확한 일치 수를 확인해야 할 때
matches = 1을 사용하십시오.matches = 1을 사용해도 모든 조합의 수치를 수집할 수 있는 것은 아닙니다. 조인이 어느 쪽을 보고할 수 있는지는
해당 조인이 어차피 수행해야 하는 작업에 따라 결정되므로, 유형과
엄격성뿐 아니라 알고리즘에도 따라 달라집니다.
해시 계열. hash, parallel_hash, grace_hash는 항상 서로 동일하게 동작합니다.
ANY, SEMI, ANTI 조인은 해시 테이블에 키당 하나의 행만 유지하므로 오른쪽 수치를 사용할 수 없습니다. 중복된 오른쪽 행은 저장되지 않으므로 개수를 셀 수도 없습니다. 다른 왼쪽 행이 이미 상대 행을 차지해 왼쪽 행의 출력을 억제하는 조인에서는 왼쪽 수치를 사용할 수 없습니다. 이 경우 출력된 행 수는 일치한 행 수보다 적게 집계됩니다.
any_join_distinct_right_table_keys를 활성화하면 ANY가 이전 RightAny 의미 체계로 전환됩니다. 이 의미 체계는 왼쪽 행마다 하나의 행을 출력하므로 양쪽 개수를 모두 유지합니다. 그러면 ANY RIGHT와 ANY FULL은 양쪽을 모두 보고하고, ANY INNER는 SEMI LEFT로 재작성됩니다.
Join 테이블 엔진도 엔진에 선언된 유형과 엄격성을 사용하여 동일한 표를 따릅니다. Join(ALL, INNER, …)는 양쪽을 보고하고, Join(ANY, LEFT, …)는 어느 쪽도 보고하지 않습니다.
머지 알고리즘. full_sorting_merge와 parallel_full_sorting_merge는 네 가지 ALL 유형, ANY INNER, ANY LEFT, ANY RIGHT, ASOF, ASOF LEFT를 지원합니다. ASOF와 ASOF LEFT를 제외한 모든 유형에서 양쪽을 보고합니다. ASOF와 ASOF LEFT에서는 오른쪽이 not collected입니다. 또한 matches = 1 없이도 가능합니다. 두 정렬된 입력을 순회하며 동일한 범위를 소비할 때 모든 행을 확인하므로 나중에 재구성할 필요가 없습니다.
partial_merge는 ALL INNER, ALL LEFT, ALL RIGHT, ALL FULL, ANY INNER, ANY LEFT, SEMI LEFT를 지원합니다. 네 가지 ALL 유형에서는 양쪽을 보고하며, 오른쪽에는 matches = 1이 필요합니다. ANY INNER, ANY LEFT, SEMI LEFT에서는 오른쪽이 not collected입니다.
direct. 왼쪽만 해당합니다. 오른쪽은 행으로 구체화되지 않는 키-값 저장소이므로 Right: 줄 자체가 없습니다.
CROSS, COMMA 및 상수 ON. 위에 설명한 대로 어느 쪽도 해당하지 않습니다.
두 알고리즘이 모두 수치를 보고하는 경우 그 수치는 일치합니다. 머지 알고리즘은 더 많은 정보를 제공할 뿐, 무엇을 일치로 간주하는지에 대해서는 서로 다르지 않습니다.
알고리즘별 행
hash 및 parallel_hash 조인과 Join 테이블 엔진에서는 Hash table: 행이 오른쪽 테이블을 기반으로 구축된 해시 테이블을 설명합니다:
unique keys <unique_keys>— 빌드 스테이지에서 해시 테이블에 저장된 고유 키 수입니다.memory <peak_memory>— 빌드 스테이지에서 해시 테이블이 사용한 최대 메모리입니다.
grace_hash 조인에서는 Hash table: 줄에 조인이 메모리 제한에 맞춰 조정된 방식도 추가로 표시되며, Spill: 줄에는 데이터가 디스크에 기록되었는지가 표시됩니다:
buckets <buckets>— 실행이 끝날 때 grace hash 조인에서 사용된 버킷 수입니다. 항상2의 거듭제곱입니다.rehashes <rehashes>— 메모리 제한에 맞추기 위해 버킷 수를 2배로 늘린 횟수입니다.Spill:— 디스크 스필 발생 여부를 나타내는yes/no플래그입니다. 스필이 발생한 경우left spilled <left_spilled_bytes>및right spilled <right_spilled_bytes>는 왼쪽(probe)과 오른쪽(build) 측에서 스필된 압축 바이트 수를 표시합니다. 스필이 발생하지 않은 경우에는 해당 줄이Spill: no로 표시됩니다.
partial_merge 조인의 경우 Right: 줄에는 오른쪽 테이블의 버퍼링 및 정렬 방식에 관한 추가 정보가 포함되며, 정렬 시간은 Stage (build) 및 Stage (probe) 줄에 표시됩니다:
size <right_size>— 오른쪽 테이블 블록의 메모리 크기입니다.blocks <right_blocks>— 오른쪽 테이블이 버퍼링된 블록 수입니다.storage <in-memory|external>— 오른쪽 테이블이 메모리에 들어갔는지(in-memory), 아니면 디스크로 스필되었는지(external)를 나타냅니다.external인 경우 추가로spilled <spilled_bytes>가 디스크에 기록된 압축 바이트 수를 표시합니다.sort time <sort_time>— 오른쪽 테이블을 정렬하는 데 소요된 시간(빌드 스테이지)과 들어오는 각 왼쪽 블록을 정렬하는 데 소요된 시간(프로브 스테이지)입니다.sort share <sort_share>%— 스테이지time백분율은 전체 쿼리의 실행 시간에서 차지하는 비율인 반면, 이는 해당 스테이지의 자체 작업 시간(프로세서 경과 시간의 합)에서sort time이 차지하는 비율입니다.
full_sorting_merge 조인에서는 공통된 Left: 및 Right: 줄만 출력됩니다.
direct 조인에서는 오른쪽이 행으로 구체화되지 않고 직접 조회되는 키-값 저장소이므로 Left: 줄만 출력됩니다.
CROSS 또는 COMMA 조인과 키 동등 조건이 없는 모든 ON 섹션에서는 Buffer: 줄이 오른쪽 테이블이 메모리에 보관된 방식을 설명하고, Spill: 줄이 디스크로 스필되었는지를 표시합니다:
memory <peak_memory>— 버퍼링된 오른쪽 테이블이 점유한 최대 메모리입니다.compressed <yes|no>— 버퍼링된 블록 중 하나 이상이 압축되었는지 나타냅니다. 압축된 블록이 하나라도 있으면 리더는 저장된 모든 블록의 압축을 해제합니다.Spill:—grace_hash와 동일한yes/no플래그이며,right spilled <right_spilled_bytes>는 디스크에 기록된 압축 후 바이트 수를 보고합니다.
matched not collected를 보고합니다. 상수 프레디케이트는 모든 왼쪽 행을 모든 오른쪽 행과 매칭하거나 전혀 매칭하지 않으므로, 개별 행 중 어떤 행이 매칭되었는지 확인할 방법이 없습니다.
Join 테이블 엔진을 대상으로 조인을 수행하면 사전 구축된 테이블을 설명하는 Hash table: 줄과 함께 양쪽 정보가 모두 표시됩니다. 오른쪽은 쿼리별 빌드의 행 수가 아니라 엔진에 저장된 행 수를 나타냅니다.
프로세서별 시간
processors = 1인 경우 각 스테이지 아래에 추가 줄이 출력되며, 해당 스테이지의 프로세서 전반에 걸친 경과 시간 분포를 보여줍니다.
<n>은 해당 단계에 있는 프로세서의 수입니다. median과 max 사이의 큰 차이는 병렬 프로세서 간의 부하 편차를 나타냅니다.
EXPLAIN ESTIMATE
Query
Query
Response
EXPLAIN WHATIF
SELECT 쿼리에서 얼마나 효과가 있을지 추정합니다. CREATE HYPOTHETICAL INDEX로 하나 이상의 후보를 정의한 다음 EXPLAIN WHATIF SELECT ...를 실행하면 각 후보별로 적용 가능 여부, 예상 읽기 마크 수, 예상 바이트 수, 스킵 비율을 확인할 수 있습니다.
구문
empirical—1(기본값)은 메모리에서 baseline으로 걸러진 그래뉼에 인덱스를 적용해 스킵 비율(상한값)을 측정합니다.0은 해당 경로를 건너뜁니다. 어느 쪽이든empirical이 결과를 생성하지 못하면(비활성화되었거나 인덱스를 메모리에서 평가할 수 없는 경우) 추정기는 컬럼 통계로 대체하고, 이마저도 사용할 수 없으면 마지막으로 적용 가능성만 요약한 결과로 대체합니다.
source— 추정치가 산출된 방식입니다.empirical: 기준선 프루닝이 적용된 그래뉼을 기준으로 메모리에서 인덱스를 구축한 뒤, 해당 인덱스가 건너뛸 그래뉼 수를 계산했습니다. 이는 상한값입니다. 자세한 내용은CREATE HYPOTHETICAL INDEX의 제한 사항을 참조하십시오.statistical: 컬럼 통계를 바탕으로 도출됩니다. empirical이 비활성화된 경우(empirical = 0) 또는 empirical이 결과를 산출하지 못했고 관련 컬럼에 컬럼 통계가 정의되어 있을 때 사용됩니다.applicability_only: 인덱스는 프레디케이트에 적용할 수 있지만 empirical 추정과 statistical 추정 모두 결과를 산출하지 못한 경우입니다(예:empirical = 0이고 컬럼 통계가 정의되지 않은 경우). 보수적인 상한값으로skip_ratio: 0.0%를 보고합니다.
sampled_parts/sampled_marks—<baseline-pruned> / <total in the table>. 테이블에서 PK, 파티션, 기존 인덱스 프루닝을 거친 뒤 남은 비율, 즉 hypothetical index의 입력이 되는 범위를 보여줍니다.est_bytes— 읽기 바이트 수의 추정치입니다. 테이블의 평균 행 크기를 바탕으로 계산하므로 근사치이며, 스토리지와 Compression에 따라 달라집니다. 기준선 행은 쿼리가 행을 읽을 때만 표시되며, 각 후보 행은 기준선 바이트 추정치를 알 수 있을 때만 표시됩니다.
WHATIF와 SELECT 사이에 인라인으로 작성하며, SETTINGS keyword는 없습니다(다른 EXPLAIN 변형이 옵션을 받는 방식과 동일합니다).
테이블에 hypothetical index가 정의되어 있지 않으면 EXPLAIN WHATIF는 status: not_applicable와 함께 생성하라는 힌트를 보고합니다.
결합 행(여러 후보)
두 개 이상의 후보를 empirical 방식으로 평가하면 EXPLAIN WHATIF는 후보별 행 뒤에 (combined: idx_a, idx_b, ...)라는 이름의 추가 블록 1개를 덧붙입니다. 이 블록은 해당 인덱스들을 모두 동시에 적용했을 때의 전체 효과를 보고합니다. 실제 읽기에서는 그래뉼이 모든 스킵 인덱스를 통과한 경우에만 유지되므로, 결합 추정치는 후보별 생존 그래뉼의 교집합이 됩니다. 따라서 skip_ratio는 가장 성능이 좋은 단일 후보보다 최소한 같거나 더 높습니다. 상호 보완적인 인덱스는 함께 더 많이 프루닝하고, 중복되는 인덱스는 결과를 바꾸지 않습니다.
source: empirical인 후보만 반영됩니다. 결합된 행은 각 후보의 그래뉼별 생존 Set의 교집합으로 만들어지기 때문입니다. statistical 또는 applicability_only로 추정된 후보에는 그래뉼별 데이터가 없으므로 제외됩니다. 따라서 결합된 블록은 최소 2개의 후보가 경험적 추정치를 생성한 경우에만 나타나며, 그렇지 않으면(예: empirical = 0인 경우) 생략됩니다. 추정 필드는 후보별 경험적 블록과 동일하지만, elapsed_us는 0입니다 — 결합된 추정치는 새로운 스캔이 아니라 후보별 스캔에서 파생되기 때문입니다. 합성된 (combined: ...) 이름은 보고서 레이블일 뿐이며 force_data_skipping_indices와 함께 사용할 수 없습니다.
경험적 예시
minmax는 100개의 마크를 1개로 걸러낼 수 있습니다 — skip_ratio: 99.0%. (est_bytes는 평균 행 크기를 기준으로 한 추정치이므로 정확한 값은 달라질 수 있습니다.)
통계 예시
컬럼 통계는 기본적으로 비활성화되어 있습니다. statistical 경로를 테스트하려면 먼저 관련 컬럼에 이를 정의하고 구체화 mutation이 완료될 때까지 기다리십시오:
b < 10의 컬럼 통계 선택도(selectivity)에서 나오며(10000개 행 중 약 10개 행), skip_ratio의 상한값으로 보고됩니다. sampled_parts / sampled_marks는 없으며, 데이터를 읽지 않았습니다.
두 경로 모두 사용할 수 없으면(예: empirical = 0이고 컬럼 통계가 정의되지 않은 경우), 추정기는 source: applicability_only와 보수적인 skip_ratio: 0.0%를 보고합니다.
EXPLAIN TABLE OVERRIDE
Query
Query
Response
검증이 완전하지 않으므로, 쿼리가 성공하더라도 재정의로 인해 문제가 발생하지 않는다고 보장할 수는 없습니다.