SELECT COUNT(*) 가 0 을 돌려준다. HDFS 경로에는 파일이 분명히 있다.
먼저 데이터가 실제로 보이는지 본다. COUNT(*) 는 통계에서 답을 가져올 수 있으므로 원본을 직접 읽는 쿼리와 결과가 다를 수 있다.
SELECT * FROM mytable LIMIT 10;
SELECT COUNT(*) FROM mytable;
다음으로 테이블이 가리키는 경로를 확인하고 그 아래에 파일이 있는지 본다.
DESCRIBE FORMATTED mytable;
hdfs dfs -ls -R /user/hive/warehouse/mydb.db/mytable | head
파티션이 등록되지 않은 경우가 가장 흔하다. 외부 도구가 HDFS 에 디렉터리를 만들어 파일을 넣어도 Metastore 는 알지 못한다. 파티션을 등록해야 조회된다.
MSCK REPAIR TABLE mytable;
SHOW PARTITIONS mytable;
ALTER TABLE mytable ADD IF NOT EXISTS PARTITION (dt='2024-09-27')
LOCATION '/user/hive/warehouse/mydb.db/mytable/dt=2024-09-27';
MSCK REPAIR 는 디렉터리 이름이 키=값 형태일 때만 동작한다. 규칙에 맞지 않는 경로는 인식하지 않으므로 ALTER TABLE ... ADD PARTITION 으로 직접 붙인다.
스키마와 파일 형식이 어긋난 경우. 테이블은 STORED AS TEXTFILE 인데 실제 파일이 Parquet 이라면 행을 읽지 못한다. 구분자가 다르면 전부 한 컬럼으로 들어가고 조건절에서 걸러진다. DESCRIBE FORMATTED 의 InputFormat 과 SerDe 를 실제 파일과 대조한다.
통계가 틀어진 경우. Hive 는 hive.compute.query.using.stats 가 켜져 있으면 COUNT(*) 를 통계값으로 답한다. 통계가 오래됐으면 0 이 나올 수 있다.
SET hive.compute.query.using.stats=false;
SELECT COUNT(*) FROM mytable;
ANALYZE TABLE mytable COMPUTE STATISTICS;
ANALYZE TABLE mytable PARTITION (dt) COMPUTE STATISTICS;
권한 문제. 쿼리를 실행하는 사용자가 데이터 경로를 읽지 못하면 오류 대신 빈 결과가 나오는 경우가 있다. hdfs dfs -ls 를 같은 사용자로 실행해 확인한다.
Impala 와 결과가 다른 경우. 두 엔진은 메타데이터 캐시를 따로 가진다. Impala 쪽에서 갱신한다.
INVALIDATE METADATA mydb.mytable;
REFRESH mydb.mytable;
MSCK REPAIR TABLE 은 파티션이 수만 개인 테이블에서 매우 오래 걸리고 Metastore 에 부하를 준다. 적재 파이프라인에서 파티션을 그때그때 등록하도록 만드는 편이 낫다.