比方说,我有一个按日期划分的配置单元表,其数据作为Parquet文件存储在S3中。我们还假设对于特定分区(日期),最初有20
条记录。
如果我随后删除原始文件并将带有50
记录的新Parquet文件放在同一文件夹中,我是否需要删除并重新创建该分区以反映新数据?
我的理解是,我们不必重新创建分区。因此,我尝试从相应的文件夹中删除旧数据并保留新数据,而没有“更新” Hive分区。但是,当我在该日期拍摄count(*)
时,它仍然显示为20
条记录而不是50
。再次删除并创建分区后,它开始显示正确的计数。这是预期的行为吗?
答案 0 :(得分:1)
Hive使用统计信息优化诸如select count(*)
之类的简单查询。如果设置了此属性:
set hive.compute.query.using.stats=true;
然后,Hive将从元数据中存储的统计信息中进行计数。
用新文件替换文件时,统计信息保持不变。删除分区后,所有相关统计信息也被删除,这就是为什么重新创建分区后计数正确的原因。
另请参阅以下答案:HIVE select count() non null returns higher value than select count()-在这种情况下,谓词可防止使用统计信息。
这种行为是完全可以预期的。您可以
set hive.compute.query.using.stats=false;
要关闭统计信息用于查询结果的计算,您的分区重新创建实际上会执行相同的操作,因为它删除了统计信息,这就是为什么不使用统计信息并扫描文件的原因。
或者您可以分析表以更新统计信息并将上述参数设置为true,因此下次您将执行简单聚合时,它将快速运行:
ANALYZE TABLE tablename [PARTITION(partcol1[=val1], partcol2[=val2], ...)]
COMPUTE STATISTICS
对于具有50条记录的小文件,仅性能差异不是很大。但是最好更新统计信息,优化器也可以使用它来构建最佳查询计划。
此处有更多详细信息:analyze table
如果您使用INSERT OVERWRITE
插入数据,则可以启用统计信息自动收集:
set hive.stats.autogather=true;