兩種方式,分別查詢數據有多少行:
hive (gmall)> select * from ods_log;
Time taken: 0.706 seconds, Fetched: 2955 row(s)
hive (gmall)> select count(*) from ods_log;
2959
兩次查詢結果不一致的原因分析
hive (gmall)>
drop table if exists ods_log;
CREATE EXTERNAL TABLE ods_log (`line` string)
PARTITIONED BY (`dt` string) -- 按照時間創建分區
STORED AS -- 指定存儲方式,讀數據採用LzoTextInputFormat;
INPUTFORMAT 'com.hadoop.mapred.DeprecatedLzoTextInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION '/warehouse/gmall/ods/ods_log' -- 指定數據在hdfs上的存儲位置
;
這是當時創建表時的語句,指定了存儲格式爲lzo,然後執行了爲lzo文件創建索引的命令
hadoop jar /opt/module/hadoop-3.1.3/share/hadoop/common/hadoop-lzo-0.4.20.jar com.hadoop.compression.lzo.DistributedLzoIndexer -Dmapreduce.job.queuename=hive /warehouse/gmall/ods/ods_log/dt=2020-06-14
所以在HDFS上的hive裏存着lzo格式數據和lzo.index索引文件,這便於對文件進行切片。
- 但是
select * from ods_log
不執行MR操作,默認採用的是ods_log建表語句中指定的DeprecatedLzoTextInputFormat
,能夠識別lzo.index
爲索引文件。 select count(*) from ods_log
執行MR操作,默認採用的是CombineHiveInputFormat
,不能識別lzo.index
爲索引文件,將索引文件當做普通文件處理。更嚴重的是,這會導致LZO文件無法切片。