Hive 는 hive.compute.query.using.stats=true 일 때 COUNT(*) · MIN · MAX 같은 질의를 메타스토어에 저장된 통계로 답한다. 잡이 뜨지 않고 즉시 값이 나오면 이 경로를 탄 것이다. 통계가 낡아 있으면 실제 행 수와 다른 값이 나온다.
실제 데이터를 세게 하려면 세션에서 이 설정을 끈다.
SET hive.compute.query.using.stats=false;
SELECT COUNT(*) FROM db.tbl;
SELECT /*+ NO_SCAN */ COUNT(*) ... 같은 힌트는 Hive 에 없다. NOSCAN 은 ANALYZE TABLE 의 옵션이지 조회 힌트가 아니다. COUNT 질의에만 통계를 끄는 별도 설정도 없으므로, 필요한 세션에서만 위 설정을 끄는 방식으로 쓴다.
ANALYZE TABLE db.tbl COMPUTE STATISTICS;
ANALYZE TABLE db.tbl COMPUTE STATISTICS FOR COLUMNS;
ANALYZE TABLE db.tbl PARTITION (bse_dt='20241024') COMPUTE STATISTICS;
COMPUTE STATISTICS 는 행 수 · 파일 수 · 전체 크기를 채우고, FOR COLUMNS 는 컬럼별 distinct 수 · NULL 수 · min/max 를 채운다. 조인 순서와 조인 방식(map join 여부)을 옵티마이저가 정할 때 쓰이므로 큰 테이블일수록 컬럼 통계가 중요하다.
NOSCAN 을 주면 파일 크기만 보고 행 수는 건드리지 않는다. 데이터 양이 커서 전체 스캔이 부담스러울 때 쓴다.
ANALYZE TABLE db.tbl COMPUTE STATISTICS NOSCAN;
DESCRIBE FORMATTED db.tbl 의 Table Parameters 또는 메타스토어의 TABLE_PARAMS · PARTITION_PARAMS 에서 numRows 가 비어 있거나 -1 이면 통계가 없는 것이다. 주로 세 가지 경우다.
ANALYZE TABLE 을 한 번도 돌리지 않은 테이블, hive.stats.autogather=false 로 적재한 테이블, 그리고 Hive 가 아닌 엔진이 쓴 데이터다. 세 번째가 실무에서 가장 흔하다. Spark 나 외부 프로세스가 HDFS 에 파일을 직접 떨어뜨리면 메타스토어 통계는 갱신되지 않으므로 적재 후 ANALYZE TABLE 을 따로 돌려야 한다.
hive.stats.autogather 는 Hive 가 수행한 INSERT 에만 적용된다.
잘못된 통계가 남아 옵티마이저를 오도할 때는 통계 프로퍼티만 지운다. 데이터에는 영향이 없다.
ALTER TABLE db.tbl UNSET TBLPROPERTIES ('numRows', 'rawDataSize', 'COLUMN_STATS_ACCURATE');
Impala 와 메타스토어를 공유하는 환경이면 한쪽에서 통계를 지우면 다른 쪽에도 그대로 보인다. Impala 의 DROP STATS 도 같은 메타스토어를 건드리므로 Hive 쪽 통계가 함께 사라진다.