我在HDFS中创建了一个外部表table1
,其中包含类型为string
的单个分区列column1
,我正在使用Hive从中获取数据。
由于数据存在于配置单元元存储本身中,因此以下查询按预期在1秒内完成。SHOW PARTITIONS table1;
上面命令的结果也确保了所有分区都在元存储中。我也运行了MSCK REPAIR TABLE table1
来确保所有分区信息都在元存储中。但是下面的查询需要10分钟才能完成。SELECT min(column1) from table1;
为什么此查询执行完整的mapreduce任务只是为了确定分区column1
的最小值,而所有值都已存在于元存储中?
还有一个用例,其中配置单元检查完整的表数据,而不使用分区信息。SELECT * FROM (SELECT * FROM table1 WHERE column1='abc') q1 INNER JOIN (SELECT * FROM table1 WHERE column1='xyz') q2 ON q1.column2==q2.column2
在这样的查询中,Hive也不使用分区信息,而是扫描所有分区,如column1='jkl'
关于这种行为的任何指针?我不确定以上两种情况是否是由于相同的原因。
1条答案
按热度按时间uelo1irk1#
这是因为数据的存储和访问方式。
SHOW PARTITIONS table1;
需要1秒,因为此数据直接来自元数据表。SELECT min(column1) from table1;
需要几分钟的时间,因为此数据来自HDFS,并在hive检查所有实际数据后计算得出。为了测试它,如果你运行这个
explain SELECT min(column1) from table1;
,你会看到查询遍历所有的分区(和所有的数据),然后找到最小值。这就像检查所有的数据来找到最小值一样好。请注意分区不是一个索引,而是它的不同的物理文件夹来存储数据文件,以便更快地访问。如果运行explain sql,您将看到SQL正在访问min()sql情况下的所有分区(我在随机college_marks列上创建了分区)-