一、Hive中常用到的基础知识

一、Hive中常用到的基础知识

    • 《简介》
        • 1、表的数据类型说明
        • 2、Hive 数据仓库支持的文件格式
        • 3、Hive各种文件格式的特点
    • 一、Beeline连接Hive
    • 二、Hive执行HQL文件
        • 1、hql文件:hive_test.hql
        • 2、执行文件内容:hive -f /tmp/lijia/hive_test.hql
    • 三、Hive创建表
        • 1、Hive表分为内部表和外部表
        • 2、通过LIKE创建表:会创建结构完全相同的表,但是没有数据
        • 3、HIVE表装载数据
            • 2.1:本地加载
            • 2.2:HDFS文件加载
            • 2.3:通过关键字”PARTITION“ 标识加载数据
        • 4、通过AS SELECT 创建表
        • 5、表的操作
        • 6、修改表文件格式和组织
        • 7、关于视图表的用途及创建
    • 四、Hive 数据仓库注释显示为乱码问题
        • 1、查看Hive数据库的编码:show create database hive;
        • 2、执行如下sql,修改表的编码:
    • 五、Hive 创建动态分区
        • 1、首先要把作为字段的分区创建为分区字段
        • 2、根据如下操作
        • 3、加入动态分区设置参数
    • 六、Hive 桶表
        • 1、基本概念:
        • 2、桶表的创建 注:只能通过Hive创建,使用Impala创建会失败
        • 3、间接加载数据
        • 4、桶表操作
    • 七、Hive的优化
        • 1、表连接优化
        • 2、用 INSERT INTO 替换 UNION ALL
        • 3、ORDER BY & SORT BY
        • 4、TRANSFORM + PYTHON
        • 5、LIMIT 语句快速出结果
        • 6、本地模式
        • 7、并行执行
        • 8、调整Mapper和Reducer的个数
            • 8.1、Map阶段优化
            • 8.2、Reduce阶段的优化
            • 8.3、Hive合并输入输出文件
        • 9、严格模式
            • 9.1、set hive.mapred.mode=strict
        • 10、数据倾斜
    • 八、Hive创建外部表CSV数据中含有逗号问题处理
        • 1、在不能修改示例数据结构的情况下,这里需要使用Hive提供的Serde,在Hive1.1版本中提供了多种Serde,此处的
        • 2、创建包含Map类型的表
        • 3、创建Struct类型的表
    • 九、Hive表中的数据进行压缩
        • 1、压缩详解
        • 2、Hive的Parquet表配置压缩
        • 3、Hive表数据被删除之后的去向


以下是本篇文章正文内容,如有错误麻烦请指出。 谢谢 !!!


《简介》

1、表的数据类型说明

Hive的parquet表支持的数据类型:

INT,TINYINT,SMALLINT,BIGINT,FLOAT,STRING,	BOOLEAN,
CHAR,VARCHAR,DECIMAL,DOUBLE,BINARY,TIMESTAMP

Impala的parquet表支持的数据类型:

TINYINT,SMALLINT,INT,BIGINT,BOOLEAN,FLOAT,DOUBLE,DECIMAL,STRING,CHAR,VARCHAR,TIMESTAMP
2、Hive 数据仓库支持的文件格式

Hive的文件存储格式包括:textfile, sequencefile, rcfile, orc, parquet

1)TextFile
	每一行都是一条记录,每行都以换行符(\ n)结尾。数据不做压缩,磁盘开销大,数据解析开销大。可结合
Gzip、Bzip2使用(系统自动检查,执行查询时自动解压),但使用这种方式,hive不会对数据进行切分,从而
无法对数据进行并行操作。
2)SequenceFile
	是Hadoop API提供的一种二进制文件支持,其具有使用方便、可分割、可压缩的特点。
	支持三种压缩选择:NONE, RECORD, BLOCK。 Record压缩率低,一般建议使用BLOCK压缩。
3)RCFile
	是一种行列存储相结合的存储方式。首先,其将数据按行分块,保证同一个record在一个块上,避免读一个记
录需要读取多个block。其次,块数据列式存储,有利于数据压缩和快速的列存取。
4)AVRO
	是开源项目,为Hadoop提供数据序列化和数据交换服务。您可以在Hadoop生态系统和以任何编程语言编写的
程序之间交换数据。Avro是基于大数据Hadoop的应用程序中流行的文件格式之一。
5)ORC文件代表了优化排柱状的文件格式。
	ORC文件格式提供了一种将数据存储在Hive表中的高效方法。这个文件系统实际上是为了克服其他Hive文件
格式的限制而设计的。Hive从大型表读取,写入和处理数据时,使用ORC文件可以提高性能。
6)Parquet
	是一个面向列的二进制文件格式。Parquet对于大型查询的类型是高效的。对于扫描特定表格中的特定列的
查询,Parquet特别有用。Parquet格式使用压缩Snappy,gzip;目前Snappy默认。
3、Hive各种文件格式的特点
1)TextFile默认的文件格式,行存储。建表时不指定存储格式即为textfile,导入数据时把数据文件拷贝至hdfs不进行处理。
	a.优点:最简单的数据格式,便于和其他工具(Pig, grep, sed, awk)共享数据,便于查看和编辑;加载较快。
	b.缺点:耗费存储空间,I/O性能较低;Hive不进行数据切分合并,不能进行并行操作,查询效率低。
	c.适用于小型查询,查看具体数据内容的测试操作。
2)SequenceFile含有键值对的二进制文件,行存储。
	a.优点:可压缩、可分割,优化磁盘利用率和I/O;可并行操作数据,查询效率高;
	b.缺点:存储空间消耗最大;对于Hadoop生态系统之外的工具不适用,需要通过text文件转化加载。
	c.适用于数据量较小、大部分列的查询。
3)RcFile行列式存储。先将数据按行分块,同一个record在一个块上,避免读一条记录需要读多个block;然后块数据列式存储。
	a.优点:可压缩,高效的列存取;查询效率较高;存储空间最小;查询的效率最高。
	b.缺点:加载时性能消耗较大,需要通过text文件转化加载;读取全量数据性能低;加载的速度最低。
4)ORC
	a.优化后的rcfile,行列式存储。
	b.优缺点与rcfile类似,查询效率最高。
	c.适用于Hive中大型的存储、查询。
5)Parquet列存储
	a.优点:更高效的压缩和编码;不与任何数据处理技术绑定,可用于多种数据处理框架(Hive, Impala, Presto查询
	引擎;MapReduce, Spark计算框架;Avro, Thrift, PB数据模型 )。
	b.缺点:不支持update, insert, delete, ACID
	c.适用于字段数非常多,无更新,只取部分列的查询。

一、Beeline连接Hive

第一种连接方式

1、启动 hiveserver2
2、beeline -u jdbc:hive2://IP:10000 -n hive

第二种连接方式

1、执行 beeline 命令
2、接着执行 !connect jdbc:hive2://IP:10000
3、根据2的提示输入用户 hive 密码 ppwd1234

二、Hive执行HQL文件

1、hql文件:hive_test.hql
内容:
	DROP TABLE DEFAULT.USER_INFO_TEST;
	CREATE TABLE DEFAULT.USER_INFO_TEST (name VARCHAR(40),
	age INT,
	gender VARCHAR(10)  )
	ROW FORMAT DELIMITED FIELDS TERMINATED BY ' ' LINES TERMINATED BY '\n'
	STORED AS TEXTFILE;
2、执行文件内容:hive -f /tmp/lijia/hive_test.hql

三、Hive创建表

1、Hive表分为内部表和外部表
外部表删除表不删除数据文件,而内部表会同数据一起删除。
注:内部表与外部表有个关键字 ”EXTERNAL“ 标识,外部表可以通过关键字 ”LOCATION“ 指定数据文件在hdfs
    上的目录

内部表:

CREATE TABLE DEFAULT.USER_INFO_TEST (name VARCHAR(40),
age INT,
gender VARCHAR(10)
) 
ROW FORMAT DELIMITED FIELDS TERMINATED BY '#' LINES TERMINATED BY '\n'
STORED AS TEXTFILE;

外部表:

CREATE EXTERNAL TABLE DEFAULT.USER_INFO_TEST2 (name VARCHAR(40),
age INT,
gender VARCHAR(10)
) 
ROW FORMAT DELIMITED FIELDS TERMINATED BY '#' LINES TERMINATED BY '\n'
STORED AS TEXTFILE;

外部表指定文件存放目录

CREATE EXTERNAL TABLE DEFAULT.USER_INFO_TEST3 (name VARCHAR(40),
age INT,
gender VARCHAR(10)
) 
ROW FORMAT DELIMITED FIELDS TERMINATED BY '#' LINES TERMINATED BY '\n'
LOCATION "/tmp/USER_INFO_TEST3";

分区表:

CREATE TABLE IF NOT EXISTS TDSHDATA.T03_AGREEMENT (`AGMT_NUM` CHAR(40) COMMENT '协议号'
,`AGMT_MODIFIER_NUM` CHAR(8) COMMENT '协议修饰符'
,`AGMT_CATEG_CD` CHAR(2) COMMENT '协议类别代码'
,`ETL_PROC_DT` TIMESTAMP COMMENT 'ETL首次插入日期') 
COMMENT '协议表'
PARTITIONED BY(`AGMT_SRC_SYS_ID` CHAR(4) COMMENT '协议来源系统编号')  
STORED AS parquet;
2、通过LIKE创建表:会创建结构完全相同的表,但是没有数据
CREATE TABLE TABLENAME LIKE TBNAME2;
3、HIVE表装载数据
注:通过LOAD加载数据,分为本地加载和HDFS加载,通过关键字”LOCAL“标识
2.1:本地加载
LOAD DATA LOCAL INPATH '/home/data/xxx.txt' OVERWRITE INTO TABLE TABLENAME;
2.2:HDFS文件加载
LOAD DATA  INPATH '/home/data/xxx.txt' OVERWRITE INTO TABLE TABLENAME;
2.3:通过关键字”PARTITION“ 标识加载数据
LOAD DATA  INPATH '/home/data/xxx.txt' OVERWRITE INTO TABLE TABLENAME PARTITION (PART1 = 'DATE');
4、通过AS SELECT 创建表
注:此方法会存入数据。但是这个不能用于创建外部表。
CREATE TABLE TBNAME AS SELECT * FROM TBNAME2;
5、表的操作
,删除表,删除数据库,删除分区,添加分区,模糊查询表,修改表名,添加字段,修改字段
清空表数据:TRUNCATE TABLE TABLENAME;
删除表:DROP TABLE IF EXISTS TABLENAME;
删除数据库:DROP DATABASE IF EXISTS DATABASENAME;    注:数据库要为空
删除数据库:DROP DATABASE IF EXISTS TDSHDATA_BAK CASCADE;   注:强制删除库
删除分区:ALTER TABLE TABLENAME DROP IF EXISTS PARTITION(P_COLUMNS = 'VALUES');   
		 注:表要存在分区字段
添加分区:ALTER TABLE TABLENAME ADD IF NOT EXISTS ADD PARTITION(P_COLUMNS = 'VALUES');   注:表要存在分区字段
模糊查询表:SHOW TABLES LIKE '*NAME*';
修改表名:ALTER TABLE TABLENAME1 RENAME TO TABLENAME2;
添加字段:ALTER TABLE TABLENAME ADD COLUMNS(COLUMNS_NAME COLUMNS_TYPE COMMENT '中文名');
添加字段:ALTER TABLE TABLENAME CHANGE COLUMN OLDER_COLUMN_NAME NEW_COLUMN_NAME 
		 NEW_TYPE COMMENT '新的中文名' [FIRST|AFTER COLUMNS_NAME];
注: [FIRST|AFTER COLUMNS_NAME] 表示修改的字段放置的位置,
	FIRST表示放置第一位,
	AFTER COLUMNS_NAME表示放在该字段的后一位。
6、修改表文件格式和组织
ALTER TABLE TABLENAME SET FILEFORMAT FILE_FORMAT_NAME; 
注:这只是改变了表的文件格式,实际的数据文件格式没有改变。
ALTER TABLE TABLENAME CLUSTERED BY (COLUMN1, COLUMN2, COLUMN3, ...)
[SORTED BY(COLUMN1, COLUMN2, ...)] INTO NUM_BUCKETS BUCKETS;
7、关于视图表的用途及创建

视图表创建:

CREATE VIEW IF NOT EXISTS DATABASE_VIEW.VIEW_TABLE_NAME 
AS SELECT * FROM DATABASE.TABLE_NAME;

应用视图表的原因:

	主要还是因为对表管理的安全考虑,视图表实际不存放数据,使用的数据还是源表中的数据,只能对视图表查
询操作,其他操作对视图表无效!

四、Hive 数据仓库注释显示为乱码问题

1、查看Hive数据库的编码:show create database hive;
如果编码为UTF-8,需要通过执行sql:alter database hive default character set latin1;
修改为hive的默认编码:latin1。(Latin1)
2、执行如下sql,修改表的编码:
cd /data/mysql/data/mysql-5.7.20/bin
./mysql -u root -p'mysqlroot' --socket=/data/mysqldata/3306/mysql.sock
2.1:use hive;
2.2:alter table COLUMNS_V2 modify column COMMENT varchar(256) character set utf8;
2.3:alter table TABLE_PARAMS modify param_value varchar(4000) character set utf8;
2.4:alter table PARTITION_PARAMS modify param_value varchar(4000) character set utf8;
2.5:alter table PARTITION_KEYS modify pkey_comment varchar(4000) character set utf8;
2.6:alter table INDEX_PARAMS modify param_value varchar(4000) character set utf8;
	 刷新:flush privileges; 

五、Hive 创建动态分区

1、首先要把作为字段的分区创建为分区字段
2、根据如下操作
INSERT INTO TABLE A PARTITION(A.COLUMNS) SELECT COLUMNS1, COLUMNS2 FROM B;导入动态分区

例如:

CREATE TABLE B (S VARCHAR(20),
 D VARCHAR(20),
 F VARCHAR(20),
 G VARCHAR(20)
) STORED AS TEXTFILE;

CREATE TABLE A (S VARCHAR(20),
D VARCHAR(20),
F VARCHAR(20)
) PARTITIONED BY (G VARCHAR(20))
STORED AS PARQUET;
3、加入动态分区设置参数
set hive.exec.dynamic.partition=true; -- 开启动态分区
set hive.exec.dynamic.partition.mode=nonstrict; -- 设置Hive允许创建动态分区
set hive.exec.max.dynamic.partitions.pernode=1000;  -- 表示每个Map或Reducer可以允许创建的最大动
态分区个数,默认100,超出会报错
set hive.exec.max.dynamic.partitions=3000; --设置Hive允许一个动态分区语句允许创建最大动态分区的
个数,超出会报错!
set hive.exec.max.created.files=10000(默认) -- 全局可以创建的最大文件个数,超出报错;
插入语句:INSERT INTO TABLE A PARTITION(G) SELECT S, D, F, G FROM B;

六、Hive 桶表

1、基本概念:
1.1、桶表是对某一列数据进行哈希取值以将数据打散,然后放到不同的文件中存储;
1.2、在Hive分区中,分区的数据量过于庞大时,建议使用桶;
1.3、在分桶时,对指定字段的值进行hash运算得到hash值,并使用hash值除以桶的个数做取余运算得到的值
	 进行分桶,保证每个桶中有数据但每个桶中数据不一定相等;做hash运算时,hash函数的选择取决于分桶字
	 段的数据类型;
1.4、分桶后的查询效率比分区后的查询效率更高。
2、桶表的创建 注:只能通过Hive创建,使用Impala创建会失败
注:如果没有加入 SORTED BY(字段) 会导致数据可能不会分桶。
CREATE TABLE TABLENAME(ID INT, 
AGE INT, 
NAME VARCHAR(30))
CLUSTERED BY(ID) SORTED BY(ID) INTO 4 BUCKETS
ROW FORMAT DELIMITED FIELDS TERMINATED BY '#' LINES TERMINATED BY '\n'
STORED AS TEXTFILE;
3、间接加载数据
桶表不能通过Load的方式加载数据,只能从另一张表中插入数据
例如:INSERT INTO TABLE TEST02 SELECT * FROM TEST01;
4、桶表操作
4.1、环境配置,使Hive能够识别通
	 设置如下配置:vim ~/.hiverc
		添加:set hive.enforce.bucketing=true
		注:~/.hiverc 原有内容如下:
		set hive.cli.print.current.db=true
		set hive.cli.print.header=true

4.2、修改桶表中bucket数量
	ALTER TABLE TABLENAME CLUSTERED BY(ID) SORTED BY(AGE) INTO 10 BUCKETS;
	
4.3、Hive中的抽样查询
	SELECT * FROM TABLENAME TABLESAMPLE(BUCKET X OUT OF Y ON FIELD_NAME);
	注:X表示从那个桶开始抽取,Y表示相隔多少桶再次抽取。
	Y必须为分桶数量的倍数或者因子,比如分桶数为6,Y为6,则表示只从桶中抽取1个bucket的数据;若Y为3,
	则表示从从中抽取6/3=2个bucket的数据。
	
4.4、Hive视图 (按需查询,提高查询效率)
	 例如:CREATE VIEW BKTVIEW AS SELECT ID, NAME, AGE FROM TABLENAME;
	 注:创建视图只是创建一个与源表的映射,视图中的字段由用户按需决定。

七、Hive的优化

1、表连接优化
1.1、将大表放后头
	 Hive假定查询中最后一张表是大表,它会将其它表缓存起来,然后扫描最后那个表。因此通常需要将小表
	 放前面,或者标记那张表是大表:/*streamtable(TABLENAME)*/。
1.2、使用相同的连接键
	 当对3个或者更多个表进行join连接时,如果每个on子句都使用相同的连接键的话,那么只会产生一个MR Job。
1.3、尽量早地过滤数据
	 减少每个阶段的数据量,对于分区表加分区,同时只选择需要使用到的字段。
1.4、尽量原子化操作
	 尽量避免一个SQL包含复杂逻辑,可以使用中间表来完成复杂的逻辑。
2、用 INSERT INTO 替换 UNION ALL
2.1、如果 UNION ALL 的部分个数大于2,或者每个 UNION ALL 部分的数据量很大,应该拆成多个 INSERT INTO 
	 语句,实际测试过程中,执行的时间能提升50%。
3、ORDER BY & SORT BY
3.1、ORDER BY:对查询结果进行全局排序,消耗时间长。需要设置:set hive.mapred.mode=nostrict。
3.2、SORT BY:局部排序,并非全局排序,提高效率。
4、TRANSFORM + PYTHON
4.1、一种嵌入在Hive取数流程中的自定义函数,通过TRANSFORM语句可以把在Hive中不方便实现的功能在
	 Python中实现,然后写入Hive中。
	 注:语法:SELECT TRANSFORM(FIELD_NAME) using '**.py' AS FIELD_NAME FROM {TABLENAME};
		如果Python脚本外还有其他依赖资源,可以使用ADD ARVHIVE。
5、LIMIT 语句快速出结果
5.1、一般情况下,LIMIT语句还是需要执行整个查询语句,然后再返回部分结果。
注:解决办法
有一个配置属性可以开启,避免这种情况---对数据源进行抽样
	5.1.1、hive.limit.optimize.enable=true --- 开启对数据源进行采样的功能;
	5.1.2、hive.limit.row.max.szie --- 设置最小的采样容量;
	5.1.3、hive.limit.optimize.limit.file --- 设置最大的采样样本数。
	缺点:有可能部分数据永远处理不到。
6、本地模式
6.1、对于小数据集,为查询触发执行任务消耗的时间 > 实际执行Job的时间,因此可以通过本地模式,
	 在单台机器上(或某些时候在单个进程上)处理所有的任务。
		set oldjobtracker=${hiveconf:mapred.job.tracker};
		set mapred.job.tracker=local;
		set mapred.tmp.dir=/home/edward/tmp;
		SQL语句:set mapred.job.tracker=${oldjobtracker};
		
6.2、可以通过设置属性
	hive.exec.mode.local.auto的值为true,来让Hive在适当的时候自动启动这个优化,也可以将配置写在
$HOME/.hiverc文件中。
6.3、当一个Job满足如下条件才能真正使用本地模式
	6.3.1、Job的输入数据大小小于参数:
		hive.exec.mode.local.auto.inputbytes.max(默认是128MB)
	6.3.2、Job的Map数必须小于参数
		Hive.exec.mode.local.auto.tasks.max(默认4)
	6.3.3、Job的Reduce数必须为0或1
		可用参数:hive.mapred.local.mem(默认0),控制child jvm 使用的最大内存数。
7、并行执行
7.1、Hive会将一个查询转化为一个或者多个阶段,包括:MapReduce阶段、抽样阶段、合并阶段、LIMIT阶段等。			
	默认情况下,一次只执行一个阶段,不过如果某些阶段不是相互依赖,是可以并行执行的。
	set hive.exec.parallel=true --- 可以开启并发执行;
	set hive.exec.parallel.thread.number=16 --- 同一个SQL允许最大的并行度,默认为8,会比较耗系统资源。
8、调整Mapper和Reducer的个数
8.1、Map阶段优化
8.1.1、Map个数主要的决定因素有:(Map执行时间:Map任务启动和初始化的时间+逻辑处理的时间)
	Input的文件总个数;
	Input的文件大小;
	集群设置的文件块大小。
8.1.2、减少MaP数
	若有大量小文件(小于128M),会产生多个Map,处理方法:(单位字节)
	set mapred.max.split.size=100000000 -- 一个Split最大大小
	set mapred.min.split.size.per.node=100000000; --- 一个节点上Split的至少大小
	set mapred.min.split.size.per.rack=100000000; --- 一个交换机下Split至少大小
	set hive.input.format=org.apache.hadoop.hive.ql.CombineHiveInputFormat
	注:以上三个参数确定合并文件块的大小,大于文件块大小128M的,按照128M来分割;
		若小于128M大于100M的,按照100M来分割,把那些小于100M的(包括小文件和分割大文件剩下的)进
		行合并。
	set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
	注:执行前进行小文件合并。
	重建目标表将物理分区切分成多份,如下:
		Create table new_table_name as select * from table_name distribute by rand(10);
8.1.3、增加Map数。
	当Input的文件都很大,任何逻辑复杂,Map执行非常慢的时候,可以考虑增加Map数来使得每个Map处理的数
据量减少,从而执行任务的执行效率。
	set mapred.reduce.tasks=20;
8.2、Reduce阶段的优化

调整方式:

第一种:参数设置
	set hive.exec.reducers.bytes.per.reducer=1G;
	set hive.exec.reducers.max=999;
第二种:调整参数
	set mapred.reduce.tasks=10;
	一般根据输入文件的总大小,用它的estimation函数来自动计算Reduce的个数:
	Reduce个数=InputFileSize / bytes.per.reducer
8.3、Hive合并输入输出文件
	如果Hive的输入文件是大量的小文件,而每个文件启动一个Map的话是对Yarn资源的浪费,同样Hive输出的文件
也远远小于HDFS的块大小,对数据后续的处理是不利的,即需要做如下处理优化:
	8.3.1、合并输入小文件
		参数	参数解释	值
		mapred.max.split.size	每个Map最大输入文件大小	256M
		mapred.min.split.size.per.node	一个节点上split的文件至少大小	100M
		mapred.min.split.size.per.rack	一个交换机下Split的文件至少大小	100M
		hive.input.format	执行Map前进行小文件合并	org.apache.hadoop.hive.ql.io.CombineHiveInputFormat
	8.3.2、合并输出小文件
		参数	参数解释	值
		hive.merge.mapfiles -- 在Map-only的任务结束时合并小文件	True
		hive.merge.mapredfiles -- 在Map-Reduce的任务结束时合并小文件	True
		hive.merge.size.per.task	-- 合并文件的大小	256M
		hive.merge.smallfiles.avgsize	 -- 当输出文件的平均大小小于该值时启动一个独立的Map-Reduce任务进行
		文件Merge	16M
9、严格模式
9.1、set hive.mapred.mode=strict
--- 防止用户执行一些意想不到的不好的影响查询;
--- 分区表,必须选定分区范围;
--- 对于使用ORDER BY的查询,要求必须使用LIMIT语句,因为ORDER BY为了执行牌勋过程会将所有的结果数据分发到同一个Reducer中进行处理;
--- 限制笛卡尔积查询:两张表JOIN时,必须要有ON条件。
10、数据倾斜
表现:任务长时间维持在99%(或100%),查看任务监控页面,发现只有少量(一个或几个)Reduce子任务没有
	 未完成。以为其处理的数据量和其他的Reduce差异过大。单一Reduce的记录数与平均记录数差异过大,通常可
	 能达到3倍甚至更多,最长时长远大于平均时长。
原因:  KEY分布不均,数据本事的特性,建表是考虑不周,某些SQL语句本身就有数据倾斜
	Join:其中一个表较小,但是KEY集中,分发到某一个或者几个Reduce上的数据远高于平均值;
	Join:大表与大表,但是分桶的判断字段0值或者空值过多,这些空值都有一个Reduce处理,非常慢;
	Group By: Group By维度过小,某值得数量过多,处理某值的Reduce非常耗时;
	Count、Distinct:某特殊值过多,处理此特殊值Reduce耗时。
	参数调节:hive.map.aggr=true

八、Hive创建外部表CSV数据中含有逗号问题处理

1、在不能修改示例数据结构的情况下,这里需要使用Hive提供的Serde,在Hive1.1版本中提供了多种Serde,此处的
数据属于CSV格式,所以这里使用默认的org.apache.hadoop.hive.serde2.OpenCSVSerde类进行处理。
建表语句:
	CREATE EXTERNAL TABLE CSVTABLE(
	COL1 STRING,
	COL2 STRING,
	COL3 STRING
	) ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.OpenCSVSerde'
	WITH SERDEPROPERTIES("separatorChar" = ",",
	"quoteChar" = "\"",
	"escapeChar" = "\\"
	) STORED AS TEXTFILE
	LOCATION '/TEM/HIVE/';
2、创建包含Map类型的表
建表语句:
	CREATE EXTERNAL TABLE MAPTABLE(COL1 STRING,
	COL2 STRING,
	COL3 MAP
	) ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
	COLLECTION ITEMS TERMINATED BY '|'
	MAP KEYS TERMINATED BY ":"
	STORED AS TEXTFILE
	LOCATION '/TEM/HIVE/';
注:Map类型里定义了Key和Value的数据类型,
	 Map类型中定义的字段与示例数据中 “name:fayson|sex:男|age:18”,该数据以k-v方式存储。
	 Collection items terminated by "|", 表示Map中的每个k-v直接以“|”分割,
	 MAP KEYS TERMINATED BY ":",表示k-v之间数据以“:”分割。
查询数据的SQL使用:
	select COL1, COL2, COL3['name'], COL3['age'], COL3['sex'] from MAPTABLE;
3、创建Struct类型的表
建表语句:
CREATE EXTERNAL TABLE STRUCTTABLE(COL1 STRING,
COL2 STRING,
COL3 STRUCT
) ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
COLLECTION ITEMS TERMINATED BY ':'
STORED AS TEXTFILE
LOCATION '/TEM/HIVE/';

九、Hive表中的数据进行压缩

1、压缩详解
查看hive支持的压缩格式:set io.compression.codecs;
2、Hive的Parquet表配置压缩
2.1、创建Parquet表:
		create table mytable(a int,b int) 
		stored as parquet
		tblproperties(‘parquet.compression’=’snappy’);
		注:如果原先创建的表没有指定压缩,后续可以通过修改表属性添加表的压缩:
			Alter table mytable set tblproperties(‘parquet.compression’=’snappy’)
			或者在写入的时候执行:set parquet.compressio’=snappy;
		注:不过只能影响后续入库的数据,原来的数据是不会压缩的,采用压缩之后大概可以降低1/3的存储大小!
3、Hive表数据被删除之后的去向
	Hive表数据删除之后,数据临时存放目录:/user/登录的用户/.Trash/(hdfs路径)
	注:需要定期删除,否则时间长了会占用大量的hdfs空间!!!

好记性不如笔记来的实在!!!

你可能感兴趣的:(#,Hive组件,hadoop,hive)