hive执行select count(*) 返回0,但是select * 有数据

首先说一下,会以下的情况有以上的结果
hive表分区,数据正好在hive分区目录里面,然后执行下面语句

alter table test add partition(dt='2020-01-01');

下面列举4种操作hdfs文件和hive表映射的情况。

1.使用标志的load方式,加载数据到分区
hdfs dfs -rm -r -f /test/data1
hdfs dfs -mkdir /test/data1

drop table dept1;

create external table  dept1(
id int,
name string,
area string
) partitioned by (dt string)
row format delimited fields terminated by ','
location '/test/data1';

# load 相当于一个剪切的功能,并且不用走mr
load data inpath "/test/dept.txt" into table dept1 partition(dt='2020-01-01');

执行select count()和select *
文件权限 rwx
select count(
) 结果非0
select * 正常显示数据

2.使用分区,先创建对应的数据目录,然后使用alter 加载数据
#注意上面的情况以及把文件加载走了,load相当于剪切所以需要重新put文件
hdfs dfs -rm -r -f /test/data2
hdfs dfs -mkdir /test/data2

drop table dept2;
create external table  dept2(
id int,
name string,
area string
) partitioned by (dt string)
row format delimited fields terminated by ','
location '/test/data2';

hdfs dfs -mkdir /test/data2/dt=2020-01-01;
hdfs dfs -cp /test/dept.txt   /test/data2/dt=2020-01-01/

alter table dept2 add partition(dt='2020-01-01');

执行select count()和select *
文件权限 rw
select count(
) 结果为0
select * 正常显示数据

3.创建不分区表,使用load的方式加载数据
hdfs dfs -rm -r -f /test/data3
hdfs dfs -mkdir /test/data3

drop table dept3;
create external table  dept3(
id int,
name string,
area string
)
row format delimited fields terminated by ','
location '/test/data3';

load data inpath "/test/dept.txt"  into table dept3;

执行select count()和select *
文件权限 rwx
select count(
) 结果非0
select * 正常显示数据

4.创建不分区表,直接把数据put到表对应文件夹
hdfs dfs -rm -r -f /test/data4
hdfs dfs -mkdir /test/data4

drop table dept4;
create external table  dept4(
id int,
name string,
area string
)
row format delimited fields terminated by ','
location '/test/data4';

hdfs dfs -cp /test/dept.txt  /test/data4/

执行select count()和select *
文件权限 rw
select count(
) 结果非0
select * 正常显示数据

结论

基于上面的四种情况,在创建分区表的时候,有的人会直接把数据放到对应的分区文件夹下面,然后alter add partition这种加载数据的方式执行select count(*)返回0,没有执行mr任务,是直接读取表级统计信息里面的数据的,不执行mr。

解决办法
  1. 重新创建,使用load正规的方式加载
    2.set hive.compute.query.using.stats=false ;
    这个配置控制是否使用talbe的统计信息
    默认的hive.compute.query.using.stats为true,表示读取表级统计信息里面的数据,设置为false,这样不读取统计数据,执行mr任务。

下面是对hive.compute.query.using.stats的解释
为新创建的表和表分区(例如使用INSERT OVERWRITE语句创建的表)启用表级统计信息的自动收集。该参数不生成列级别的统计信息,例如由CBO生成的统计信息。如果禁用,管理员必须使用ANALYZE table语句为新生成的表和表分区手动生成表级统计信息。
可是为什么在默认值为true的情况下,使用load加载的却任然执行了mr,这一部分应该需要看源码的,目前我还没有找到这一段源码,但是我对比了两个边的统计信息,使用以下的语句查看表的统计信息

desc etended  <tableName>

发现使用alter加载数据和使用load加载数据有区别
下面是使用load加载的截图


image.png

下面是使用alter加载的截图


image.png

这里 alter的desc信息里面有一个COLUME_STATS_ACCURATE的数据,但是使用load加载数据的表却没有,然后我把dept1,使用了下面的语句生成统计信息之后,执行count() 发现也不走mr了,所以,这里可以判断,是否存在COLUME_STATS_ACCURATE将会影响到select count()是否执行mr

analyze table dept1 compute statistics for columns;

得到以上的结论,我们在深入的探究一下,如果我们加载了新的数据放到dept1中,dept1里面的统计信息是否会更新。


image.png

在我重新的将数据放到dept1的另外一个partition里面的之后,在查询count(*),却发现重新走mr进行计算了,
然后desc extended dept1,发现没有了COLUME_STATS_ACCURATE的数据


image.png

由此可以得出一个结论,使用load加载数据之后,会将之前的统计数据COLUME_STATS_ACCURATE,删除掉,防止历史数据影响到正常使用。
得到了这个上面的这个结论,我又想,那之间的使用alter的dept2,是怎么又COLUME_STATS_ACCURATE的数据的呢,所以我重新建了一张表用来验证。

原来一张表在建立之初就是默认使用


image.png
综上得出结论

首先,有数据但count(*)返回0,这个是因为hive.compute.query.using.stats=true导致的,但是并不是hive.compute.query.using.stats=true,所有的表都会count(*)=0,首先是要分为表是否是partition ,当表是分区表,在会自动的有COLUME_STATS_ACCURATE的数据(这里的无论hive.compute.query.using.stats是否是true都会有),然后load数据到具体的分区,COLUME_STATS_ACCURATE的就会消失,但是使用alter加载数据到分区,COLUME_STATS_ACCURATE的数据是不会消失的。
当表不是普通的不分区表,是没有COLUME_STATS_ACCURATE的数据的,这个时候无论使用load或者是alter加载数据,执行count(*)都会走mr的。这也就是为什么dept4同样是使用alter的方式,但是执行count(*)的时候取走mr的原因。但是当执行analyze table 命令之后,也会生成统计信息,在执行count(*)不会走mr的。

hive.compute.query.using.stats之前的版本的默认值是fasle,然后现在是ture,具体从哪个版本我不太清楚。如果设置为true,Hive在执行某些查询时,例如select count(1),只利用元数据存储中保存的状态信息返回结果。 为了收集基本状态信息,需要将hive.stats.autogather属性配置为true。为了收集更多的状态信息,需要运行analyze table查询命令,例如下面的语句收集sales_order_fact表的统计信息。

analyze table dept1 compute statistics for columns;
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,014评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,796评论 3 386
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,484评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,830评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,946评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,114评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,182评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,927评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,369评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,678评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,832评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,533评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,166评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,885评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,128评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,659评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,738评论 2 351