쿼리 옵션

쿼리 옵션 (Query Options)

실행, 진단, 리소스 사용을 형성하는 쿼리 수준 스위치예요.

출처: 문서

본문

쿼리 옵션은 실행 엔진을 선택하고, 런타임 제한을 제어하며, 진단을 조정할 수 있게 해주는 쿼리별 스위치예요.

가장 중요한 옵션

  • useMultistageEngine 고급 SQL 기능이 필요한 쿼리에 multi-stage 엔진을 선택해요.
  • timeoutMs Pinot가 쿼리에 사용할 시간의 상한을 정해요.
  • clientQueryId 추적과 취소를 위해 쿼리에 안정적인 식별자를 부여해요.
  • explainPlanVerbose Pinot에 더 풍부한 계획 출력을 요청해요.
  • maxExecutionThreads 비싼 쿼리의 동시성을 제한해요.
  • numGroupsLimit, minSegmentGroupTrimSize, minServerGroupTrimSize, accurateGroupByWithoutOrderBy 같은 group-by 메모리/정확도 노브(아래 Grouping algorithm 참조).
SET useMultistageEngine = true;
SET timeoutMs = 5000;
SET clientQueryId = 'query-2026-03-24-001';
SELECT city, COUNT(*)
FROM stores
GROUP BY city
LIMIT 10;

옵션 이름

문서화된 키는 정규 camelCase를 사용해요(예: timeoutMs, useMultistageEngine, minSegmentGroupTrimSize). Pinot는 SET / OPTION 절을 파싱할 때 인식된 옵션 이름을 대소문자 구분 없이 그 정규 형태로 해석하므로 SET timeoutms = 5000은 timeoutMs처럼 처리돼요.

아래 표의 정규 이름을 사용하는 것이 좋아요. 데이터 쿼리의 경우 클러스터 수준 pinot.broker.query.option.validationMode가 SQL SET 문이나 레거시 OPTION(...) 절을 통해 제공된 알 수 없는 키를 제어해요. 기본값 NONE은 호환성을 위해 보존하고, WARN은 알 수 없는 키를 로깅하며, REJECT는 쿼리를 실패시켜요. 가까운 오타는 timeoutMs 같은 인식된 옵션에 대한 제안을 만들 수 있어요. SQL 쿼리는 내부 rlsFilters* 옵션을 설정할 수도 없어요. 브로커는 필요할 때 파싱 후 행 수준 보안 옵션을 추가해요.

이 검증은 SQL DQL 경로에 한정돼요. 자유 형식 옵션은 REST/JSON queryOptions 필드에서 하위 호환성을 유지하며, INSERT INTO FILE 같은 DML SET 속성은 자유 형식으로 남아요. 통합이 사용자 지정 옵션 이름에 의존한다면 SQL 텍스트에 넣는 대신 요청의 queryOptions 필드로 보내세요.

기본 LIMIT 동작, group-by 꼬리 트리밍, ORDER BY 대 정렬 없는 group-by에 대해서는 Querying Pinot를 참조하세요.

SQL 옵션 정책

운영자는 cluster config API를 통해 pinot.broker.query.option.validationMode와 pinot.broker.query.option.legacySyntaxMode를 변경할 수 있어요. 둘 다 재시작 없이 실행 중인 브로커에 적용돼요. 전자는 데이터 쿼리의 알 수 없는 SQL 옵션 이름에 대해 NONE(기본값), WARN, REJECT를 받아요. 후자는 DML을 포함한 모든 문 유형의 OPTION(key=value) 접미사에 대해 ALLOW(기본값), IGNORE, REJECT를 받아요. REJECT는 호출자가 SQL SET을 대신 사용하도록 안내해요. 롤링 업그레이드 중에는 IGNORE나 REJECT를 설정하기 전에 모든 브로커가 legacySyntaxMode를 지원할 때까지 기다리세요. 이전 브로커는 접미사를 계속 적용해요.

요청 게이트웨이가 SQL 텍스트가 신뢰된 요청 옵션을 덮어쓰지 못하게 해야 한다면 요청의 queryOptions(REST)나 gRPC 메타데이터에 sqlOptionsMode를 전달해요. ALLOW(기본값)는 SQL SET과 레거시 OPTION(...) 값을 요청 옵션 위에 병합하고, IGNORE는 SQL에 포함된 옵션을 버리며, REJECT는 해당 키와 함께 QUERY_VALIDATION을 반환해요. 예를 들어 REST 요청은 sql 문자열과 함께 "queryOptions": "sqlOptionsMode=IGNORE;timeoutMs=5000"을 포함할 수 있어요. 이 모드는 SQL 내부에 제공될 때는 인정되지 않아요. 잘못된 모드는 SQL에 옵션이 없어도 QUERY_VALIDATION으로 실패해요.

옵션을 언제 쓰는가

테이블 구성을 변경하지 않고 동작을 바꾸고 싶을 때 쿼리 옵션을 사용해요.

일반적인 경우:

  • 사용자 대면 요청의 타임아웃 낮추기
  • 조인이 필요한 쿼리에 대해 multi-stage 실행 강제하기
  • 로그와 취소를 위한 사용자 지정 쿼리 ID 연결
  • 단일 쿼리의 실행 리소스 넓히기/좁히기

더 깊은 노브가 있는 곳

일부 쿼리 동작은 원시 옵션 목록 대신 전용 페이지로 제어돼요.

이 페이지가 다룬 내용

이 페이지는 주요 쿼리 수준 스위치, 설정하는 이유, 관련 제어를 처리하는 전용 페이지를 다뤘어요.

다음 단계

쿼리를 추적하거나 중지해야 한다면 Query cancellation을 읽어 보세요. 결과 전달을 형성해야 한다면 Cursor pagination을 읽어 보세요.

지원되는 쿼리 옵션

Key 설명 기본 동작
timeoutMs 쿼리의 타임아웃(밀리초) 테이블/브로커 수준 타임아웃 사용
extraPassiveTimeoutMs multi-stage 쿼리의 경우, Pinot가 상위 스테이지나 mailbox 데이터를 기다릴 때 사용하는 수동적(passive) 데드라인에 이 밀리초를 더함. timeoutMs의 능동적 쿼리 데드라인은 바꾸지 않음. 브로커 수준 구성(기본값 100)
enableNullHandling 고급 null 처리를 활성화함(Null value support 참조, 0.11.0부터) false (비활성)
explainPlanVerbose EXPLAIN 쿼리에 대해 상세 결과 반환(0.11.0부터) false (상세하지 않음)
useMultistageEngine 쿼리를 실행하는 데 multi-stage 엔진 사용(0.11.0부터) false (single-stage 엔진 사용)
sqlOptionsMode SQL SET 또는 레거시 OPTION(...)에 포함된 옵션에 대한 요청 수준 정책: ALLOW, IGNORE, REJECT. REST queryOptions나 gRPC 메타데이터에 제공( SQL 내부 아님). ALLOW (SQL 옵션이 요청 옵션을 덮어씀)
useApproximateFunction 적격한 정확 distinct-count 및 percentile 집계를 SMART 변형으로 재작성할지 true, 정확하게 유지할지 false로 설정. 단일-stage 전용. 테이블, 클러스터, 브로커 설정; 어디에도 없으면 false
useMSEToFillEmptyResponseSchema 0행을 반환하는 single-stage 쿼리에 대해 multi-stage 엔진 컴파일러로 더 정확한 빈 결과 스키마를 채우려 시도. false
enableMaterializedViewRewrite 적격 single-stage 쿼리에서 브로커 측 물리화 뷰 재작성이 허용되는지 제어. 생략 시 기본 활성. true
maxExecutionThreads 쿼리 실행에 사용할 최대 스레드 수. 비싼 쿼리의 리소스 사용 제한에 유용. 설정 시 쿼리 값 사용; 아니면 서버 기본값/자동 선택
numReplicaGroupsToQuery replica-group 기반 라우팅이 활성화될 때 여러 replica-group을 조회하는 데 사용(0.11.0부터) 1 (같은 replica-group 내 서버만 조회)
useFixedReplica 각 세그먼트를 쿼리에 대해 일관된 복제본으로 라우팅. 테이블/브로커 수준의 fixed-replica 설정을 덮어씀. 테이블/브로커 수준 설정; 둘 다 없으면 false
sortAggregateLimitThreshold group-by 쿼리에서 모든 group key로 정렬할 때 쿼리 LIMIT가 이 임계값 아래이면 sort-aggregation 사용. 10000
sortAggregateSingleThreadedNumSegmentsThreshold 병합할 세그먼트 수가 이 임계값 아래이면 병렬 쌍별 병합 대신 단일 스레드 순차 결합 사용. CPU 코어 수
numGroupsLimit group-by 쿼리에서 새 그룹 수용을 멈추기 전 각 쿼리 연산자가 유지하는 그룹 수 상한. leaf와 intermediate 스테이지 모두에 적용. 서버 수준 구성(기본값 100000)
numGroupsWarningLimit group-by 쿼리에서 쿼리 연산자가 축적하는 그룹 수의 경고 임계값. 도달하면 경고 로깅 및 numGroupsWarningLimitReached=true 설정. 서버 수준 구성(기본값 150000)
errorOnNumGroupsLimit multi-stage group-by 쿼리에서 numGroupsLimit에 도달하면 부분 결과 대신 예외 발생. false
allowReverseOrder single-stage 선택 쿼리에서 정렬된 세그먼트를 ORDER BY ... DESC에 대해 내림차순으로 읽는 것을 허용. false
minInitialIndexedTableCapacity group-by 쿼리에서 IndexedTable 인스턴스 생성 시 사용하는 최소 초기 용량. 128
minSegmentGroupTrimSize group-by 쿼리에서 세그먼트 수준 그룹 트리밍 시 유지할 최소 그룹 수. 서버 수준 구성
minServerGroupTrimSize group-by 쿼리에서 서버 수준 그룹 트리밍 시 유지할 최소 그룹 수. 서버 수준 구성
serverReturnFinalResult group key가 서버 파티셔닝되었을 때 서버가 집계에 대해 중간 결과 대신 최종 결과를 직접 반환하도록 요청. 단일 서버 조회 시 true, 아니면 false
serverReturnFinalResultKeyUnpartitioned group key가 서버 파티셔닝되지 않았지만 집계 컬럼이 서버 파티셔닝되었을 때 사용. distinct count에 특히 유용. false
skipIndexes 어떤 인덱스를 건너뛸지(즉 스캔), 컬럼별로 지정. URL 파라미터 형식: skipIndexes='col1=inverted,range&col2=inverted'. 건너뛸 유형: sorted, range, inverted, H3. null/empty (모든 사용 가능한 인덱스 사용)
vectorNprobe IVF_FLAT, IVF_PQ, IVF_ON_DISK 벡터 검색에서 ANS 후보 수집 전 세그먼트당 조사할 inverted list 수. HNSW 및 정확-스캔 대체 경로에서는 무시. IVF의 경우 4; HNSW 및 정확-스캔 대체에서 무시
vectorExactRerank ANN 인덱스를 사용하는 벡터 검색에서 최종 top-K 반환 전 ANN 후보를 forward index의 정확 거리로 재점수화. IVF_PQ의 경우 true; HNSW 및 IVF_FLAT의 경우 false
vectorMaxCandidates vectorExactRerank=true일 때 정확 재순위화 전 검색할 ANN 후보 수. 정확 rerank 활성 시 topK * 10
vectorDistanceThreshold top-K 제한 대신 이 거리 임계값 내의 모든 결과를 반환. VECTOR_SIMILARITY 쿼리에 적용. 미설정 (top-K 검색 사용)
vectorEfSearch HNSW 검색에서 그래프 순회가 방문하는 노드 수(검색 빔 폭). IVF 및 정확-스캔 대체 경로에서 무시. 인덱스 구성에서(미설정 시 topK 기본)
vectorUseRelativeDistance HNSW 검색에서 경쟁적(상대 거리) 가지치기 토글. 비-HNSW 인덱스에서 무시. true
vectorUseBoundedQueue HNSW 검색에서 bounded top-K collector 토글. 비-HNSW 인덱스에서 무시. true
skipPlannerRules 기본 활성화된 쿼리 플래너 규칙 중 어떤 것을 비활성화할지. 쉼표 구분 규칙 이름: skipPlannerRules='FilterProjectTranspose,PruneEmptySort'. null/empty (기본 활성 규칙을 건너뛰지 않음)
usePlannerRules 기본 비활성인 규칙 중 어떤 것을 사용할지. 쉼표 구분: usePlannerRules='AggregateJoinTransposeExtended,SortProjectTranspose'. null/empty (기본 비활성 규칙 사용 안 함)
skipUpsert upsert 활성 테이블에서 upsert 효과를 건너뛰고 모든 레코드를 조회. false (대체된 레코드 제외)
upsertViewFreshnessMs SNAPSHOT 일관성 모드를 사용하는 upsert 테이블에서 upsert 뷰의 쿼리 시 신선도 창을 덮어씀. 테이블의 upsertViewRefreshIntervalMs 사용
skipUpsertView upsert 테이블 디버깅: SYNC/SNAPSHOT 일관성 모드가 유지하는 일관된 upsert 뷰를 우회해 NONE 모드처럼 조회. false
useStarTree star-tree 인덱스 디버깅에 유용(0.11.0부터). true (가능하면 star-tree 사용)
AndScanReordering 상세 설명 참조. 비활성
maxRowsInJoin 조인 연산에 허용되는 최대 행 수. 조인의 오른쪽 입력에 대한 해시 테이블 빌드 단계와 왼쪽 입력과 매칭 후 방출되는 조인 행 수 모두에 적용. 클러스터 구성 기본, 미설정 시 2^20 (1024*1024)
inPredicatePruningThreshold IN 조건자에서 Pinot가 값 기반 또는 bloom 필터 세그먼트 프루닝을 시도하는 최대 값 수를 덮어씀. 서버 inpredicate.threshold 설정(기본 10)
inPredicatePreSorted (STRING 컬럼만) IN 절의 값이 이미 정렬되어 있어 Pinot가 쿼리 시 다시 정렬할 필요가 없음을 표시. false
inPredicateLookupAlgorithm (STRING 컬럼만) IN 절 값의 사전 ID를 찾는 알고리즘: DIVIDE_BINARY_SEARCH, SCAN, PLAIN_BINARY_SEARCH. DIVIDE_BINARY_SEARCH
maxServerResponseSizeBytes 쿼리에 대해 서버별 직렬화 응답의 최대 길이(Long). 쿼리 옵션 → 테이블 구성 → 브로커 구성 우선순위
maxQueryResponseSizeBytes 쿼리에 대해 모든 서버에 걸친 최대 직렬화 응답 크기(Long). 이 값을 쿼리를 처리하는 모든 서버에 균등 분할. 위와 같은 우선순위
filteredAggregationsSkipEmptyGroups 기본 쿼리 필터와 일치하지만 필터링된 집계 FILTER (WHERE ...) 절과 일치하지 않는 그룹 계산을 피하려면 true. false (표준 SQL처럼 모든 그룹 계산)
dropResults 응답에서 resultTable을 버리도록 dropResults=true 설정. 민감한 데이터가 포함된 결과로 고객 쿼리를 메타데이터 전용으로 문제 해결하는 데 사용. false
skipUnavailableServers 디스패치가 실패하면 나머지 서버로 쿼리를 계속 보내도록 skipUnavailableServers=true 설정. false
ignoreMissingSegments 라우팅된 세그먼트가 서버에서 사용 불가능할 때 SERVER_SEGMENT_MISSING 예외 무시. false
sampler 테이블 구성에서 명명된 테이블 샘플러를 선택. 세그먼트 샘플 부분집합에 대해 쿼리 실행. 예: SET sampler='small'. null/empty (일반 라우팅)
clientQueryId 쿼리의 사용자 지정 상관 ID 및 쿼리 취소 정의. null/empty
applicationName 쿼리를 명명된 애플리케이션에 할당해 애플리케이션 수준 쿼리 할당량에 사용. Query Quotas API와 함께 사용. null/empty (애플리케이션 이름 없음)
accurateGroupByWithoutOrderBy ORDER BY/HAVING 없는 SSE GROUP BY ... LIMIT에서 서버·브로커 축소 중 사전순으로 가장 작은 group key를 유지해 결정적 부분집합 유지. false
optimizeMaxInitialResultHolderCapacity single-stage GROUP BY에서 단일 값 그룹핑 컬럼의 등식/IN 조건자를 사용해 초기 result-holder 용량을 줄임. false
traceRuleProductions 플래너 규칙 생성을 추적. SET traceRuleProductions=true로 성공적으로 새 관계를 생성한 플래너 규칙 및 전후 관계 서브트리를 수집·반환. false
excludeVirtualColumns 쿼리에서 가상 컬럼($로 시작)을 무시하고 싶을 때 사용(예: NATURAL JOIN에서 조인 조건 매칭에 참여하면 안 될 때). MSE에서 구현. false (기본적으로 모든 쿼리에서 조인 매칭 중 가상 컬럼 포함)
useSpools multi-stage 쿼리에 대해 스테이지 레벨 스풀링 활성화. 동등한 스테이지를 반복 실행 대신 재사용 가능. stage-level-spooling 참조. 브로커 수준 구성(기본 false)
usePhysicalOptimizer MSE용 Physical Optimizer 활성화. 불필요한 Exchange(셔플)를 자동 제거/단순화. useMultistageEngine=true와 함께 사용해야 함(1.4.0 도입). false (비활성)
unnestColumnPruning multi-stage UNNEST 쿼리에서 논리 플래너 경로의 미사용 통과 컬럼을 UNNEST 출력에서 제거. usePhysicalOptimizer=true면 무시. 브로커 수준 구성(기본 false)
sortExchangeCopyThreshold multi-stage ORDER BY ... LIMIT에서 유효 fetch가 이 정수 임계값 이하일 때 sort-and-limit을 sort exchange 아래로 푸시. 브로커 수준 구성(기본 10000)
inferRealtimeSegmentPartition 파티셔닝된 실시간 테이블의 multi-stage 엔진에서 저장된 세그먼트-파티션 메타데이터에 의존할 수 없을 때 실시간 세그먼트 이름에서 세그먼트 파티션 추론. false
useLiteMode Multi-stage 엔진 Lite Mode 활성화: scatter-gather 패러다임으로 MSE 쿼리 실행, leaf 스테이지 인스턴스당 반환 행 제한 구성 가능(기본 100k). useMultistageEngine=true와 usePhysicalOptimizer=true 필요(1.4.0 도입). false (비활성)
liteModeLeafStageLimit Lite Mode에서 leaf 스테이지 worker가 반환할 수 있는 최대 레코드 수를 덮어씀. 양의 정수여야 함. 브로커 수준 구성(기본 100000)
liteModeLeafStageFanOutAdjustedLimit Lite Mode에서 fan-out 조정 leaf-스테이지 제한을 양의 정수로 덮어씀. 브로커 수준 구성(미설정/비양수 시 비활성)
runInBroker Lite Mode에서 non-leaf 스테이지를 어디서 실행할지 제어. true면 scatter-gather 실행 모델을 보존하기 위해 브로커에서 실행. 브로커 수준 구성(Lite Mode 활성 시 기본 true)
useLeafServerForIntermediateStage multi-stage 쿼리에서 모든 활성 서버에서 선택하는 대신 leaf 스테이지에 선택된 것과 같은 서버를 intermediate 스테이지의 worker로 사용. false
streamStats multi-stage 쿼리에서 브로커-서버 디스패치를 레거시 unary submit 경로 대신 스트리밍 SubmitWithStream 통계 경로로 전환. 브로커 수준 구성(기본 false)
inferPartitionHint multi-stage 조인에서 조인된 테이블로부터 파티션 정보를 추론해 colocated 실행을 사용. 브로커 수준 pinot.broker.multistage.infer.partition.hint 설정을 덮어씀. 브로커 수준 구성(기본 false)
orderedPreferredPools 브로커 쿼리 라우팅을 위한 우선순위 서버 풀 목록. 파이프(|)로 구분된 풀 식별자(정수) 목록. canary 배포에 유용(1.4.0 도입). null/empty (풀 선호 없음)
workloadName CPU/메모리 회계 및 워크로드 예산 집행을 위해 쿼리를 명명된 워크로드에 할당(1.4.0 도입). null/empty (기본 워크로드에 속함)
isSecondaryWorkload 쿼리를 보조 워크로드 쿼리로 표시(1.4.0 도입). false
enableMultiClusterRouting 여러 Pinot 클러스터에 걸쳐 쿼리를 라우팅하는 멀티-클러스터 쿼리(페더레이션) 활성화. MultiClusterHelixBrokerStarter 및 논리 테이블 필요. false (로컬 클러스터에만 실행)

커서 페이징

Key 설명 기본 동작
getCursor true로 설정하면 전체 결과 집합 대신 커서를 반환. 큰 결과 집합에 유용. false (전체 결과 집합 반환)
cursorNumRows 각 커서 페이지에 포함할 행 수. getCursor=true일 때만 적용. 브로커 수준 구성

Explain Plan

Key 설명 기본 동작
explainAskingServers multi-stage 엔진의 explain 동작 제어. true면 서버에 세그먼트 계획을 요청. false면 논리 계획만 반환. 브로커 수준 구성(기본 false)

Group-By Trim

Key 설명 기본 동작
minBrokerGroupTrimSize group-by 쿼리에서 브로커 수준 그룹 트리밍 시 유지할 최소 그룹 수(SSE만). 비양수로 설정하면 브로커 수준 트림 비활성. 브로커 수준 구성(기본 5000)
mseMinGroupTrimSize multi-stage group-by 쿼리에서 중간 스테이지 집계 결과 트리밍 시 유지할 그룹 수. 서버 수준 구성(기본 5000)
groupTrimThreshold 브로커 수준 group-by 트리밍 임계값. 브로커 축소 단계에서 트림이 트리거되기 전 보유할 수 있는 최대 그룹 수 제어. 브로커 수준 구성(기본 1000000)

Multi-Stage 엔진 Group-By 스트리밍

Key 설명 기본 동작
streamingGroupByFlushThreshold multi-stage 엔진 GROUP BY에서 누적 그룹 수가 이 임계값에 도달하면 부분 group-by 결과를 플러시. 높은 카디널리티 GROUP BY 쿼리의 서버 메모리 사용을 제한. 브로커 구성이 양수면 그 값, 아니면 0(비활성)

예시: 플러시 임계값이 있는 스트리밍 Group-By

메모리 압력을 일으킬 수 있는 높은 카디널리티 GROUP BY 쿼리에 대해 스트리밍 모드를 활성화할 수 있어요.

-- Enable multi-stage engine with streaming group-by
SET useMultistageEngine = true;
SET streamingGroupByFlushThreshold = 5000;

-- Query with potentially high cardinality GROUP BY
SELECT user_id, country, COUNT(*) as event_count
FROM events
WHERE date = '2026-04-01'
GROUP BY user_id, country
LIMIT 100000;

이 예시에서 쿼리는 누적 그룹 수가 5000에 도달할 때마다 부분 group-by 결과를 플러시해 무한정 메모리 증가를 방지해요.

Multi-Stage 엔진 DISTINCT 스트리밍

Key 설명 기본 동작
streamingDistinctFlushThreshold 적격한 multi-stage DISTINCT 쿼리에서 leaf의 누적 distinct 값이 이 양의 임계값에 도달하면 플러시. 다운스트림 스테이지가 최종 중복 제거. ORDER BY 없음, leaf LIMIT > 임계값 등 조건 필요. 브로커 기본이 양수면 그 값, 아니면 비활성

큰 DISTINCT limit으로 leaf가 너무 많은 값을 축적하게 될 때 이 옵션을 사용하세요.

SET useMultistageEngine = true;
SET streamingDistinctFlushThreshold = 5000;

SELECT DISTINCT user_id
FROM events
LIMIT 1000000;

이 옵션을 gRPC 스트리밍 쿼리 경로와 함께 사용하지 마세요. 그 경로에는 플러시 간 중복을 제거할 다운스트림 스테이지가 없기 때문이에요.

조인 및 윈도우 오버플로우

Key 설명 기본 동작
joinOverflowMode 조인 연산이 maxRowsInJoin을 초과할 때 동작 제어: THROW(예외 발생) 또는 BREAK(처리 중지 후 부분 결과 반환). THROW
maxRowsInWindow 윈도우 함수 연산에 허용되는 최대 행 수. 큰 윈도우 프레임 처리 시 과도한 메모리 사용 방지. 클러스터 구성 기본, 미설정 시 2^20 (1024*1024)
windowOverflowMode 윈도우 연산이 maxRowsInWindow을 초과할 때 동작 제어: THROW 또는 BREAK. THROW

Multi-클러스터 라우팅

Key 설명 기본 동작
enableMultiClusterRouting 여러 Pinot 클러스터에 걸쳐 쿼리를 라우팅하는 멀티-클러스터 쿼리(페더레이션) 활성화. MultiClusterHelixBrokerStarter 및 논리 테이블 필요. Multi-Cluster Querying 참조. false (로컬 클러스터에만 실행)

브로커 프루닝

Key 설명 기본 동작
useBrokerPruning true로 설정하면 multi-stage leaf-stage 라우팅을 위한 브로커 측 세그먼트 프루닝 활성화. 쿼리 수준 useBrokerPruning이 적용 가능한 브로커 기본값을 덮어씀. 물리 옵티마이저 경로: 브로커 구성(기본 true); 논리 플래너 적격 leaf: 브로커 구성(기본 true)

인덱스 기반 DISTINCT

Key 설명 기본 동작
useIndexBasedDistinctOperator true일 때 적합한 인덱스 기반 DISTINCT 연산자 활성화. 단일 컬럼 SELECT DISTINCT jsonExtractIndex(...) 쿼리를 JsonIndexDistinctOperator로 라우팅하고, 사전 인코딩된 컬럼을 InvertedIndexDistinctOperator로 라우팅. false (비활성)
jsonIndexDistinctSkipMissingPath JsonIndexDistinctOperator에만 적용. true면 누락 경로 처리를 건너뜀: 4-arg 기본값을 추가하지 않고, null 처리가 활성화되어도 NULL을 추가하지 않으며, 일부 매칭 문서가 경로를 포함하지 않아도 Illegal Json Path를 던지지 않음. false (4-arg 기본값 사용/있으면, 아니면 NULL 추가 또는 Illegal Json Path 발생)
invertedIndexDistinctCostRatio InvertedIndexDistinctOperator의 비용 휴리스틱을 덮어씀. dictionaryCardinality * costRatio <= filteredDocCount일 때 bitmap inverted-index 경로 선택. 0으로 설정하면 필터가 한 행 이상 매칭될 때마다 bitmap 경로 강제. null/empty (내장 카디널리티 기반 휴리스틱 사용)

DISTINCT 조기 종료 (Single-Stage 실행)

Key 설명 기본 동작
maxRowsInDistinct DISTINCT 쿼리에서 조기 종료 전 모든 세그먼트에서 스캔할 최대 행 수. 도달하면 스캔 중지 후 부분 결과 반환. null/empty (제한 없음)
maxRowsWithoutChangeInDistinct 새 distinct 값을 생성하지 않고 스캔할 최대 행 수. distinct 값 집합이 빠르게 수렴할 때 유용. null/empty (제한 없음)
maxExecutionTimeMsInDistinct DISTINCT 쿼리의 결합 연산자를 위한 벽시계 시간 예산(밀리초). 초과하면 부분 결과 반환. null/empty (제한 없음)

이 예산은 여전히 single-stage DISTINCT 실행 경로에 의해 강제돼요. multi-stage 쿼리가 DISTINCT 처리에 single-stage leaf 경로를 사용할 때 Pinot는 이제 leaf 스테이지 이유를 V2 응답에 partialResult=true와 earlyTerminationReasons로 전파해요. 네이티브 multi-stage DISTINCT 연산자는 아직 자체적으로 이러한 경계를 강제하지 않아요.

조기 종료가 있는 DISTINCT 쿼리 예시

-- 100,000행 스캔 후 중지
SELECT DISTINCT country FROM users
OPTION (maxRowsInDistinct=100000)

-- 새 distinct 값 없이 10,000행 후 중지
SELECT DISTINCT state FROM users
OPTION (maxRowsWithoutChangeInDistinct=10000)

-- 5초 실행 후 중지
SELECT DISTINCT user_id FROM events
OPTION (maxExecutionTimeMsInDistinct=5000)

-- 여러 제한 결합
SELECT DISTINCT product_id FROM orders
OPTION (maxRowsInDistinct=50000, maxRowsWithoutChangeInDistinct=5000)

이러한 조기 종료 예산 중 하나가 초과되면 Pinot는 쿼리 엔진에 따라 이유를 다르게 표시해요.

  • Single-stage 응답 필드:
    • partialResult (boolean): 조기 종료로 결과가 부분일 때 true로 설정.
    • maxRowsInDistinctReached (boolean): maxRowsInDistinct 초과 시 true.
    • maxRowsWithoutChangeInDistinctReached (boolean): maxRowsWithoutChangeInDistinct 초과 시 true.
    • maxExecutionTimeInDistinctReached (boolean): maxExecutionTimeMsInDistinct 초과 시 true.
  • Multi-stage 응답 필드(leaf 스테이지가 DISTINCT 처리를 조기 종료할 때):
    • partialResult (boolean): true로 설정.
    • earlyTerminationReasons (string array): DISTINCT_MAX_ROWS, DISTINCT_MAX_ROWS_WITHOUT_CHANGE, DISTINCT_MAX_EXECUTION_TIME 같은 이름 하나 이상 포함.

조기 종료가 있는 SSE 응답 예시

{
  "resultTable": {
    "dataSchema": {
      "columnNames": ["country"],
      "columnDataTypes": ["STRING"]
    },
    "rows": [
      ["USA"],
      ["Canada"],
      ["Mexico"]
    ]
  },
  "numDocsScanned": 100000,
  "numEntriesScannedInFilter": 100000,
  "numEntriesScannedPostFilter": 100000,
  "totalDocs": 10000000,
  "numSegmentsQueried": 10,
  "numSegmentsProcessed": 6,
  "partialResult": true,
  "maxRowsInDistinctReached": true,
  "maxRowsWithoutChangeInDistinctReached": false,
  "maxExecutionTimeInDistinctReached": false,
  "timeUsedms": 245
}

전파된 DISTINCT 조기 종료가 있는 MSE 응답 예시

{
  "resultTable": {
    "dataSchema": {
      "columnNames": ["country"],
      "columnDataTypes": ["STRING"]
    },
    "rows": [
      ["USA"],
      ["Canada"],
      ["Mexico"]
    ]
  },
  "partialResult": true,
  "earlyTerminationReasons": ["DISTINCT_MAX_ROWS"]
}

더 알아보기 (Learn more)