前言
我们在写 HQL 有没有遇到过数据量特别大的时候比如,使用 HQL 处理起来非常复杂,非常慢,这时候我们可以使用 Hive 给加个索引来提高我们的速度。多了就不说了,我们直接开始。
一、Hive 视图
1.1 简介
Hive 中的视图和 RDBMS 中视图的概念一致,都是一组数据的逻辑表示,本质上就是一条 SELECT
语句的结果集。视图是纯粹的逻辑对象,没有关联的存储 (Hive 3.0.0 引入的物化视图除外),当查询引用视图
时,Hive 可以将视图的定义与查询结合起来,例如将查询中的过滤器推送到视图
中。
1.2 特点
不支持物化视图
只查询,不能做加载数据操作
视图的创建,只是保存一份元数据
,查询视图才执行对应的子查询
view 定义中若包含了 ORDER BY/LIMIT 语句,当查询视图时也进行了 ORDER BY/LIMIT 语句操作,view 当中定义的优先级更高 ;
Hive 视图支持迭代视图
1.3 创建视图
CREATE VIEW [IF NOT EXISTS] [db_name.]view_name -- 视图名称
[(column_name [COMMENT column_comment], ...) ] --列名
[COMMENT view_comment] --视图注释
[TBLPROPERTIES (property_name = property_value, ...)] --额外信息
AS SELECT ...;
复制代码
创建视图注意事项
CREATE VIEW 创建具有给定名称的视图。如果已经存在具有相同名称的表或视图,则会引发错误。您可以使用IF NOT EXISTS
跳过该错误。
删除基表并不会删除视图,需要手动删除视图;
视图是只读的,不能用作LOAD
/ INSERT
/ ALTER
的目标
创建视图时,如果未提供列名,则将从 SELECT 语句中自动派生列名;
一个视图可能包含 ORDER BY 和 LIMIT 子句。如果参照查询还包含这些条款,查询级别子句进行评估后视图条款(和之后在查询的任何其它操作)。例如,如果视图指定 LIMIT 5,并且引用查询执行为(从 v LIMIT 10 中选择*),那么最多将返回 5 行。
准备数据
```sql
-- 创建测试表
create table default.user(
id string , -- 主键
sex string, -- 性别
name string -- 名称
);
-- 导入数据
insert into default.user (id, sex, name)
values ("1","男","张三"),("2","女","小花"),("3","男","赵柳"),("4","男","李嘿嘿");
**创建一个测试视图**
```sql
hive (default)> create view if not exists default.user_view as select * from default.user;
OK
id sex name
Time taken: 0.181 seconds
复制代码
1.4 查询视图
-- 查询视图内容呢
select * from default.user_view;
-- 查询视图结构
desc default.user_view;
-- 查询视图详细信息
desc formatted default.user_view;
-- 查询视图 没有指定的方式跟查询所有表一样
show tables;
复制代码
1.5 删除视图
-- 模板
DROP VIEW [IF EXISTS] [db_name.]view_name;
-- 删除视图
DROP VIEW IF EXISTS user_view;
复制代码
1.6 修改视图属性
语法:
ALTER VIEW [db_name.]view_name SET TBLPROPERTIES table_properties;
table_properties:
: (property_name = property_value, property_name = property_value, ...)
复制代码
示例:
alter view default.user_view set tblproperties ('name'='DSJLG','GZH'='DSJLG')
复制代码
通过 desc formatted default.user_view;
详情信息
二、索引
2.1 简介
Hive 在 0.7.0 引入了索引的功能,索引的设计目标是提高表某些列的查询速度。如果没有索引,带有谓词的查询(如'WHERE table1.column = 10')会加载整个表或分区并处理所有行
。但是如果 column 存在索引,则只需要加载和处理文件的一部分
。
2.2 创建索引模板
CREATE INDEX index_name --索引名称
ON TABLE base_table_name (col_name, ...) --建立索引的列
AS index_type --索引类型
[WITH DEFERRED REBUILD] --重建索引
[IDXPROPERTIES (property_name=property_value, ...)] --索引额外属性
[IN TABLE index_table_name] --索引表的名字
[
[ ROW FORMAT ...] STORED AS ...
| STORED BY ...
] --索引表行分隔符 、 存储格式
[LOCATION hdfs_path] --索引表存储位置
[TBLPROPERTIES (...)] --索引表表属性
[COMMENT "index comment"]; --索引注释
复制代码
2.3 创建索引
我们在使用之前上面创建好的user
表对id
字段创建名字为user_index
,索引存储在 userindextable
索引表中
create index user_index on table user(id) as 'org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler'
with deferred rebuild in table user_index_table;
复制代码
此时索引表中是没有数据的,需要重建索引才会有索引的数据。
2.4 重建索引
hive (default)> ALTER index user_index on user rebuild ;
Query ID = root_20201015081313_879ce697-a6a4-4c38-a1a9-0e72a52feb6b
Total jobs = 1
Launching Job 1 out of 1
Number of reduce tasks not specified. Estimated from input data size: 1
In order to change the average load for a reducer (in bytes):
set hive.exec.reducers.bytes.per.reducer=<number>
In order to limit the maximum number of reducers:
set hive.exec.reducers.max=<number>
In order to set a constant number of reducers:
set mapreduce.job.reduces=<number>
Starting Job = job_1602711568359_0002, Tracking URL = http://node01:8088/proxy/application_1602711568359_0002/
Kill Command = /export/servers/hadoop-2.6.0-cdh5.14.0/bin/hadoop job -kill job_1602711568359_0002
Hadoop job information for Stage-1: number of mappers: 1; number of reducers: 1
2020-10-15 08:13:47,425 Stage-1 map = 0%, reduce = 0%
2020-10-15 08:13:48,546 Stage-1 map = 100%, reduce = 0%, Cumulative CPU 1.66 sec
2020-10-15 08:13:49,576 Stage-1 map = 100%, reduce = 100%, Cumulative CPU 2.5 sec
MapReduce Total cumulative CPU time: 2 seconds 500 msec
Ended Job = job_1602711568359_0002
Loading data to table default.user_index_table
Table default.user_index_table stats: [numFiles=1, numRows=4, totalSize=231, rawDataSize=227]
MapReduce Jobs Launched:
Stage-Stage-1: Map: 1 Reduce: 1 Cumulative CPU: 2.5 sec HDFS Read: 12945 HDFS Write: 581944 SUCCESS
Total MapReduce CPU Time Spent: 2 seconds 500 msec
OK
Time taken: 12.85 seconds
复制代码
Hive 会启动 MapReduce
作业去建立索引,建立好后查看索引表数据如下。三个表字段分别代表:索引列的值
、该值对应的 HDFS 文件路径
、该值在文件中的偏移量
。
hive (default)> select * from user_index_table;
OK
user_index_table.id user_index_table._bucketname user_index_table._offsets
1 hdfs://node01:8020/user/hive/warehouse/user/000000_0 [0]
2 hdfs://node01:8020/user/hive/warehouse/user/000000_0 [13]
3 hdfs://node01:8020/user/hive/warehouse/user/000000_0 [26]
4 hdfs://node01:8020/user/hive/warehouse/user/000000_0 [39]
Time taken: 0.047 seconds, Fetched: 4 row(s)
复制代码
2.5 自动使用索引
默认情况下,虽然建立了索引,但是 Hive 在查询时候是不会自动去使用索引
的,需要开启相关配置
。开启配置后,涉及到索引列的查询就会使用索引功能去优化查询
。
SET hive.input.format=org.apache.hadoop.hive.ql.io.HiveInputFormat;
SET hive.optimize.index.filter=true;
SET hive.optimize.index.filter.compact.minsize=0;
复制代码
2.6 查看索引
show index on user;
2.7 删除索引
删除索引会删除对应的索引表。
DROP INDEX [IF EXISTS] index_name ON table_name;
复制代码
如果存在索引的表被删除了,其对应的索引和索引表都会被删除。如果被索引表的某个分区被删除了,那么分区对应的分区索引也会被删除。
2.8 索引的原理
在指定列
上建立索引,会产生一张索引表(Hive的一张物理表
),里面字段包括:索引列的值
、该值对应的 HDFS 文件路径
、该值在文件中的偏移量
。
在执行索引字段查询时候,首先额外生成一个MapReduce job
,根据对索引列的过滤条件,从索引表中过滤出索引列的值对应的hdfs文件路径及偏移量
,输出到 hdfs 上的一个文件中,然后根据这些文件中的 hdfs 路径和偏移量,筛选原始input文件
,生成新的split
,作为整个 job 的 split,这样就达到不用全表扫描的目的。
总结
今天给大家分享了 Hive 中常用的视图和说索引,索引虽然能帮助我们提高查询效率和分组效率但它也有缺点的,创建好索引是无法自动rebuild
也就意味着修改数据和添加数据都需要手动执行rebuild
。如果频繁修改的数据就不建议使用索引
了。信自己,努力和汗水总会能得到回报的。我是大数据老哥,我们下期见~~~
>获取 Flink 面试题,Spark 面试题,程序员必备软件,hive 面试题,Hadoop 面试题,Docker 面试题,简历模板等资源请去 GitHub 自行下载 https://github.com/lhh2002/Framework-Of-BigData
评论