Hive 는 예전에 compact · bitmap 두 종류의 인덱스를 제공했고 CREATE INDEX · ALTER INDEX ... REBUILD 로 관리했다. 이 기능은 Hive 3.0 에서 완전히 제거됐다. 3.x 이상에서 CREATE INDEX 를 실행하면 문법 오류가 난다.
제거된 이유는 유지 비용 때문이다. 인덱스는 데이터가 바뀔 때마다 재작성해야 했고, 컬럼 포맷과 파티션 프루닝이 같은 효과를 훨씬 싸게 냈다.
Impala 에는 처음부터 인덱스가 없다. 두 엔진 모두 아래 수단으로 스캔량을 줄인다.
파티셔닝 — 자주 거르는 컬럼(보통 날짜)으로 디렉터리를 나눈다. WHERE 절이 파티션 키를 직접 가리킬 때만 프루닝이 걸린다.
컬럼 포맷 — ORC · Parquet 는 stripe · row group 단위로 min/max 통계를 갖고 있어 조건에 해당 없는 블록을 통째로 건너뛴다. 필요한 컬럼만 읽는 효과도 크다.
ORC bloom filter — 동등 비교가 잦은 고카디널리티 컬럼에 건다.
CREATE TABLE db.tbl (id STRING, amt DECIMAL(18,2))
PARTITIONED BY (bse_dt STRING)
STORED AS ORC
TBLPROPERTIES ('orc.bloom.filter.columns'='id', 'orc.bloom.filter.fpp'='0.05');
버킷팅 — 조인 키로 버킷을 맞춰 두면 셔플 없는 버킷 조인이 가능하다. 양쪽 테이블의 버킷 수가 배수 관계여야 한다.
구체화 뷰 — Hive 3 이상은 materialized view 와 자동 재작성을 지원한다. 반복되는 집계 질의에 쓴다.
파티션 키에 함수를 씌우면 프루닝이 걸리지 않는다. 아래 조인은 bse_dt 파티션을 전부 읽는다.
SELECT ... FROM v1 JOIN v3 ON substr(v1.bse_dt, 1, 6) = v3.bse_ym;
조건을 파티션 키 쪽에 원형으로 남기고 범위로 바꿔야 한다. 월 단위 비교라면 해당 월의 시작·끝 값을 직접 준다.
SELECT ... FROM v1 JOIN v3
ON v1.bse_dt BETWEEN concat(v3.bse_ym, '01') AND concat(v3.bse_ym, '31');
LIKE '202410%' 는 상수 접두사일 때 프루닝이 걸릴 수 있으나 엔진과 버전에 따라 다르다. 실행 계획에서 실제로 읽는 파티션 수를 확인한다.
EXPLAIN SELECT ...;