hive 为什么对分区信息(应该存储在元存储中)进行配置单元查询需要这么长时间

w3nuxt5m  于 2022-11-29  发布在  Hive
关注(0)|答案(1)|浏览(102)

我在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'
关于这种行为的任何指针?我不确定以上两种情况是否是由于相同的原因。

uelo1irk

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列上创建了分区)-

29
      Path -> Alias:
30
        hdfs://namenode:8020/user/hive/warehouse/tmp/college_marks=10.0 [tmp]
31
        hdfs://namenode:8020/user/hive/warehouse/tmp/college_marks=50.0 [tmp]
32
      Path -> Partition:
33
        hdfs://namenode:8020/user/hive/warehouse/tmp/college_marks=10.0 
34
          Partition
35
            base file name: college_marks=10.0
36
            input format: org.apache.hadoop.mapred.TextInputFormat
37
       hdfs://namenode:8020/user/hive/warehouse/tmp/college_marks=50.0 
85
          Partition
86
            base file name: college_marks=50.0
87
            input format: org.apache.hadoop.mapred.TextInputFormat
88
            output format: org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat
89
            partition values:
90
              college_marks 50.0
91

相关问题