hive中有数据 select count(*)显示为0的问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hive中有数据 select count(*)显示为0的问题相关的知识,希望对你有一定的参考价值。

参考技术A 检查表的时候
sql语句:

显示为

但是执行
sql语句:

显示为

后面加上限制1条可以正常查询。

执行下语句后,正常查询可以正常显示。

以上设置原理为

这是hive中的一个优化参数导致的,对于一些使用频率可能很高的sql会进行查询优化,会将这个参数[hive.compute.query.using.stats]设置为true(默认是false),这样的话,Hive在执行某些查询时,例如select count(1),只利用元数据存储中保存的状态信息返回结果,从而提高了响应速度

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(*)显示为0的问题的主要内容,如果未能解决你的问题,请参考以下文章

HIVE select count(*) 非 null 返回高于 select count(*) 的值

从 Hive 中的多个表中选择 count(*)

Hive:SELECT * 语句有效,但 SELECT COUNT(*) 无效

HIVE-----count(distinct ) over() 无法使用解决办法

Select * 的行计数结果 MISMATCH 和大文件的 Hive 外部表的 Select count(1)

job.split 元信息的 Hive Select Count(*) filenotfoundexception