一文教你学会Hive视图和索引

4b71a40a198d36b81e59f43fbf9116c7.jpg


前言

         咱们在写HQL有没有遇到过数据量特别大的时候好比,使用HQL 处理起来很是复杂,很是慢,这时候咱们可使用Hive给加个索引来提升咱们的速度。多了就不说了,咱们直接开始。node

e059118d211e08d59926169c37a53199.jpg

1、Hive视图

1.1 简介

         Hive 中的视图和 RDBMS 中视图的概念一致,都是一组数据的逻辑表示,本质上就是一条 SELECT 语句的结果集。视图是纯粹的逻辑对象,没有关联的存储 (Hive 3.0.0 引入的物化视图除外),当查询引用视图时,Hive 能够将视图的定义与查询结合起来,例如将查询中的过滤器推送到视图中。git

1.2 特色

  1. 不支持物化视图
  2. 只查询,不能作加载数据操做
  3. 视图的建立,只是保存一份元数据,查询视图才执行对应的子查询
  4. view定义中若包含了ORDER BY/LIMIT语句,当查询视图时也进行了ORDER BY/LIMIT语句操做,view当中定义的优先级更高 ;
  5. 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行。

准备数据github

-- 建立测试表
create  table default.user(
   id string , -- 主键
   sex string-- 性别
   name string -- 名称
);
--  导入数据
insert into default.user (id, sex, name)
values ("1","男","张三"),("2","女","小花"),("3","男","赵柳"),("4","男","李嘿嘿");

建立一个测试视图面试

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 修改视图属性

语法:apache

ALTER VIEW [db_name.]view_name SET TBLPROPERTIES table_properties; 
table_properties:
  : (property_name = property_value, property_name = property_value, ...)

示例app

alter  view  default.user_view set tblproperties ('name'='DSJLG','GZH'='DSJLG')

经过 desc formatted default.user_view;详情信息ide

48bae0480b0c3189324ba00812d3ecca.jpg

2、索引

2.1 简介

         Hive 在 0.7.0 引入了索引的功能,索引的设计目标是提升表某些列的查询速度。若是没有索引,带有谓词的查询(如'WHERE table1.column = 10')会加载整个表或分区并处理全部行。可是若是 column 存在索引,则只须要加载和处理文件的一部分oop

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,索引存储在user_index_table索引表中测试

create index user_index on table user(idas '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-1number 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;43f7c242c5fe053f0f833db4bc107003.jpg

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

相关文章
相关标签/搜索