Insert 在所有情况下都将执行相同的操作,因为 insert 不会查询您现有的数据(除非您使用 select from 自身进行插入),并且通常每个容器都会创建自己的文件,除非配置了文件合并。
如果表按日期分区,使用日期范围查询数据会更好。文件过多可能会导致性能下降,因此您可能希望在插入期间合并文件。什么是文件太多?就像每天分区数百甚至数千。每个分区有几个文件不会导致性能问题,您不需要合并它们。
插入语句将在分区目录中创建附加文件,通常不会与现有文件合并。将创建多少个文件取决于插入语句和配置设置。
最终运行的映射器或减速器的数量+配置设置将决定输出文件的数量。您可以强制它在单个减速器上运行,例如,添加“order by”子句。在这种情况下,每个分区将创建一个额外的文件,但它会运行缓慢。也distribute 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)
这些配置设置可能会在最后触发合并任务(取决于上述设置中配置的大小),它将合并现有文件以及插入新添加的文件。
有关合并的更多详细信息,请参阅此答案:https ://stackoverflow.com/a/45266244/2700344
实际上,在这种情况下,管理的或外部的表的类型并不重要。插入或选择的工作方式相同。
如果您已经有与目标表格式相同的文件,那么最快的方法是将它们放在分区目录中,而根本不使用 DML 查询。
对于 ORC 文件,您可以使用以下命令有效地合并文件:ALTER TABLE T [PARTITION partition_spec] CONCATENATE;