我正在研究一种解决方案,并发现在某些特定情况下,配置单元insert overwrite
会截断表,但在少数情况下它不会。有人请解释一下它的行为是什么吗?
为了解释这一点,我是表两个表,源和目标,并尝试使用insert overwrite
当源表具有分区
时如果源表具有分区,并且如果您编写的条件使分区不存在,那么它将不会截断主表。
create table source (name String) partitioned by (age int);
insert into source partition (age) values("gaurang", 11);
create table target (name String, age int);
insert into target partition (age) values("xxx", 99);
以下查询不会截断表,即使select不返回任何内容。
insert overwrite table temp.test12 select * from temp.test11 where name="Ddddd" and age=99;
但是,在查询后会截断表格。
insert overwrite table temp.target select * from temp.test11 where name="Ddddd" and age=11;
在第一种情况下有意义,因为分区(age = 99)不存在因此它应该进一步停止执行查询。然而,这是我的假设,不确定到底发生了什么。
当源表没有分区,但Target有时 在这种情况下,即使源表中的select语句返回0行,也不会截断目标表。
use temp;
drop table if exists source1;
drop table if exists target1;
create table source1 (name String, age int);
create table target1 (name String) partitioned by (age int);
insert into source1 values ("gaurang", 11);
insert into target1 partition(age) values("xxx", 99);
select * from source1;
select * from target1;
即使在select语句中找不到数据,以下查询也不会截断表。
insert overwrite table temp.target1 partition(age) select * from temp.source1 where age=90;
当源或目标没有分区时
在这种情况下,如果我尝试插入覆盖目标并且select语句不返回任何行,则目标表将被截断。 检查下面的例子。
use temp;
drop table if exists source1;
drop table if exists target1;
create table source1 (name String, age int);
create table target1 (name String, age int);
insert into source1 values ("gaurang", 11);
insert into target1 values("xxx", 99);
select * from source1;
select * from target1;
以下查询会截断目标表。
insert overwrite table temp.target1 select * from temp.source1 where age=90;
答案 0 :(得分:1)
最好使用术语'overwrite'
而不是truncate
,因为它是insert overwrite
期间发生的事情。
当您编写overwrite table temp.target1 partition(age)
时,您指示Hive覆盖分区,而不是所有target1表,只覆盖select将返回的分区。
空数据集不会在动态分区模式下覆盖分区。因为要覆盖的分区未知,所以应该从数据集中获取分区,并且数据集为空,无需覆盖。
如果没有分区表,已经知道它应该覆盖所有表,无关紧要,是否为空数据集。
insert overwrite
语句中的分区列应该是最后一个。并且要在目标中覆盖的分区列表=数据集返回的分区列中的值列表与源表的分区方式无关(可以从任何源表列中选择目标分区列,计算它或使用常量) ),只有返回的内容才重要。