hive执行select count(*) 返回0,但是select * 有数据
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hive执行select count(*) 返回0,但是select * 有数据相关的知识,希望对你有一定的参考价值。
参考技术A 首先说一下,会以下的情况有以上的结果
hive表分区,数据正好在hive分区目录里面,然后执行下面语句
下面列举4种操作hdfs文件和hive表映射的情况。
执行select count( )和select *
文件权限 rwx
select count( ) 结果非0
select * 正常显示数据
执行select count( )和select *
文件权限 rw
select count( ) 结果为0
select * 正常显示数据
执行select count( )和select *
文件权限 rwx
select count( ) 结果非0
select * 正常显示数据
执行select count( )和select *
文件权限 rw
select count( ) 结果非0
select * 正常显示数据
基于上面的四种情况,在创建分区表的时候,有的人会直接把数据放到对应的分区文件夹下面,然后alter add partition这种加载数据的方式执行select count(*)返回0,没有执行mr任务,是直接读取表级统计信息里面的数据的,不执行mr。
下面是对hive.compute.query.using.stats的解释
为新创建的表和表分区(例如使用INSERT OVERWRITE语句创建的表)启用表级统计信息的自动收集。该参数不生成列级别的统计信息,例如由CBO生成的统计信息。如果禁用,管理员必须使用ANALYZE table语句为新生成的表和表分区手动生成表级统计信息。
可是为什么在默认值为true的情况下,使用load加载的却任然执行了mr,这一部分应该需要看源码的,目前我还没有找到这一段源码,但是我对比了两个边的统计信息,使用以下的语句查看表的统计信息
发现使用alter加载数据和使用load加载数据有区别
下面是使用load加载的截图
下面是使用alter加载的截图
得到以上的结论,我们在深入的探究一下,如果我们加载了新的数据放到dept1中,dept1里面的统计信息是否会更新。
在我重新的将数据放到dept1的另外一个partition里面的之后,在查询count(*),却发现重新走mr进行计算了,
然后desc extended dept1,发现没有了COLUME_STATS_ACCURATE的数据
原来一张表在建立之初就是默认使用
首先,有数据但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表的统计信息。
HIVE select count(*) 非 null 返回高于 select count(*) 的值
【中文标题】HIVE select count(*) 非 null 返回高于 select count(*) 的值【英文标题】:HIVE select count(*) non null returns higher value than select count(*) 【发布时间】:2016-10-07 08:27:19 【问题描述】:我目前正在使用 Hive 进行一些数据探索,但无法解释以下行为。假设我有一个带有 master_id 字段的表(名为 mytable)。
当我计算得到的行数时
select count(*) as c from mytable
c
1129563
如果我想计算具有非空 master_id 的行数,我会得到更大的数字
select count(*) as c from mytable where master_id is not null
c
1134041
此外,master_id 似乎永远不会为空。
select count(*) as c from mytable where master_id is null
c
0
我无法解释如何添加 where 语句最终会增加行数。有没有人有任何提示来解释这种行为?
谢谢
【问题讨论】:
该表的架构是什么样的? 提供您的表架构 【参考方案1】:很可能您的查询没有使用统计信息,因为设置了此参数:
set hive.compute.query.using.stats=true;
尝试将其设置为 false 并再次执行。
或者,您可以计算表的统计信息。 见ANALYZE TABLE SYNTAX
还可以在 INSERT OVERWRITE 期间自动收集统计信息:
set hive.stats.autogather=true;
【讨论】:
非常感谢。实际上,如果我将 hive.compute.query.using.stats 设置为 false,则两个计数都匹配。 这是一个值得分析的新东西。很好。以上是关于hive执行select count(*) 返回0,但是select * 有数据的主要内容,如果未能解决你的问题,请参考以下文章
HIVE select count(*) 非 null 返回高于 select count(*) 的值
Hive:SELECT * 语句有效,但 SELECT COUNT(*) 无效