当前位置: 首页 > 知识库问答 >
问题:

配置单元如何处理插入内部分区表?

鲜于煜祺
2023-03-14

我需要将记录流插入到配置单元分区表中。表结构类似于

CREATE TABLE store_transation (
     item_name string,
     item_count int,
     bill_number int,
) PARTITIONED BY (
   yyyy_mm_dd string
);

我想了解一下Hive是如何处理内部表中的插入的。

是否将所有记录插入到yyyy_mm_dd=2018_08_31目录中的单个文件中?或者配置单元在一个分区内拆分为多个文件,如果是,什么时候拆?

如果每天有100万条记录,并且查询模式介于日期范围之间,那么下面哪一条性能好?

  1. 内部表中没有分区
  2. 按日期分区,每个日期只有一个文件
  3. 按日期分区,每个日期有多个文件

共有1个答案

陈博容
2023-03-14

Insert将在所有情况下执行相同的操作,因为Insert不会查询现有数据(除非使用select from本身进行插入),并且通常每个容器都将创建自己的文件,除非配置了文件合并。

如果按日期对表进行分区,则使用日期范围查询数据会执行得更好。文件太多可能会导致性能下降,因此您可能希望在INSERT期间合并文件。什么是文件太多?比如每天的分区都有几百甚至上千个。每个分区拥有很少的文件不会导致性能问题,您不需要合并它们。

Insert语句将在分区目录中创建其他文件,通常不会与现有文件合并。将创建多少个文件取决于insert语句和配置设置。

运行+配置设置的最终映射器或还原器的数量将决定输出文件的数量。您可以通过添加“order by”子句来强制它在单个reducer上运行。在这种情况下,每个分区将创建一个额外的文件,但它的工作速度会很慢。也可以使用distribution by partition key来减少创建的文件数,但这会触发额外的reducer阶段,并且工作速度会比map only任务慢。

您还可以使用以下设置将新文件与现有文件合并:

SET hive.merge.mapfiles=true;
SET hive.merge.mapredfiles=true;
SET hive.merge.size.per.task=128000000; -- (128MB)
SET hive.merge.smallfiles.avgsize=128000000; -- (128MB)

这些配置设置可能会在最后触发合并任务(取决于上述设置中配置的大小),它将合并现有文件以及通过插入新添加的文件。

实际上,表的类型,托管的还是外部的,在这个上下文中并不重要。Insert或select将同样工作。

如果您已经有了与目标表相同格式的文件,那么最快的方法就是将它们放在分区目录中,而完全不使用DML查询。

对于ORC文件,您可以使用以下命令有效地合并文件:alter TABLE T[PARTITION partition_spec]concatenate;

 类似资料: