Hive 物化视图

Hive3.0新特性:物化视图 materialized views

物化视图概念

在传统的数据库领域基本已经都实现了物化视图, 属于数据库的高级功能。物化视图(Materialized View)是一个包括查询结果的数据库对像,可以用于预先计算并保存表连接或聚集等耗时较多的操作的结果

这样,在执行查询时,就可以避免进行这些耗时的操作,而从快速的得到结果。使用物化视图的目的就是通过预计算,提高查询性能,当然需要占用一定的存储空间。

但是在 SQL On Hadoop 领域里支持这个特性的还不多,比较令人期待。Hive3.0 开始尝试引入物化视图,并提供对于物化视图的查询自动重写(基于Apache Calcite实现)。

值得注意的是,3.0 中提供了物化视图存储选择机制,可以本地存储在 Hive,同时可以通过用户自定义 storage handlers 存储在其他系统(如Druid)。

Hive 引入物化视图的目的就是为了优化数据查询访问的效率,相当于从数据预处理的角度优化数据访问。Hive从3.0丢弃了index索引的语法支持,推荐使用物化视图和列式存储文件格式来加快查询的速度。

物化视图、视图区别

视图是虚拟的,逻辑存在的,只有定义没有存储数据。

物化视图是真实的,物理存在的,里面存储着预计算的数据。

不同于视图,物化视图能够缓存数据,在创建物化视图的时候就把数据缓存起来了,Hive把物化视图当成一张“表”,将数据缓存。而视图只是创建一个虚表,只有表结构,没有数据,实际查询的时候再去改写SQL去访问实际的数据表。

视图的目的是简化降低查询的复杂度,而物化视图的目的是提高查询性能。

物化视图语法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
--物化视图的创建语法
CREATE MATERIALIZED VIEW [IF NOT EXISTS] [db_name.]materialized_view_name
[DISABLE REWRITE]
[COMMENT materialized_view_comment]
[PARTITIONED ON (col_name, ...)]
[CLUSTERED ON (col_name, ...) | DISTRIBUTED ON (col_name, ...) SORTED ON (col_name, ...)]
[
[ROW FORMAT row_format]
[STORED AS file_format]
| STORED BY 'storage.handler.class.name' [WITH SERDEPROPERTIES (...)]
]
[LOCATION hdfs_path]
[TBLPROPERTIES (property_name=property_value, ...)]
AS SELECT ...;

语法说明:

  1. 物化视图创建后,select查询执行数据自动落地,”自动”也即在query的执行期间,任何用户对该物化视图是不可见的

  2. 默认该物化视图可被用于查询优化器optimizer查询重写(在物化视图创建期间可以通过DISABLE REWRITE参数设置禁止使用)

  3. SerDe和storage format非强制参数,可以用户配置,默认可用hive.materializedview.serde、 hive.materializedview.fileformat

  4. 物化视图可以使用custom storage handlers存储在外部系统(如druid)

例如:

1
2
3
4
5
CREATE MATERIALIZED VIEW druid_wiki_mv
STORED AS 'org.apache.hadoop.hive.druid.DruidStorageHandler'
AS
SELECT __time, page, user, c_added, c_removed
FROM src;

目前支持物化视图的drop和show操作,后续会增加其他操作

1
2
3
4
5
6
7
8
-- Drops a materialized view
DROP MATERIALIZED VIEW [db_name.]materialized_view_name;

-- Shows materialized views (with optional filters)
SHOW MATERIALIZED VIEWS [IN database_name];

-- Shows information about a specific materialized view
DESCRIBE [EXTENDED | FORMATTED] [db_name.]materialized_view_name;

当数据源变更(新数据插入inserted、数据修改modified),物化视图也需要更新以保持数据一致性,目前需要用户主动触发rebuild

1
ALTER MATERIALIZED VIEW [db_name.]materialized_view_name REBUILD;

基于物化视图的查询重写

物化视图创建后即可用于相关查询的加速,用户提交查询query,若该query经过重写后可命中已建视图,则被重写命中相关已建视图实现查询加速。

是否重写查询使用物化视图可以通过全局参数控制,默认为true:

1
SET hive.materializedview.rewriting=true;

用户可选择性的失能物化视图的重写:

1
ALTER MATERIALIZED VIEW [db_name.]materialized_view_name ENABLE|DISABLE REWRITE;

案例:物化视图查询重写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
--1、新建一张事务表 student_trans
set hive.support.concurrency = true; --Hive是否支持并发
set hive.enforce.bucketing = true; --从Hive2.0开始不再需要 是否开启分桶功能
set hive.exec.dynamic.partition.mode = nonstrict; --动态分区模式 非严格
set hive.txn.manager = org.apache.hadoop.hive.ql.lockmgr.DbTxnManager; --
set hive.compactor.initiator.on = true; --是否在Metastore实例上运行启动线程和清理线程
set hive.compactor.worker.threads = 1; --在此metastore实例上运行多少个压缩程序工作线程。

CREATE TABLE student_trans (
sno int,
sname string,
sdept string)
clustered by (sno) into 2 buckets stored as orc TBLPROPERTIES('transactional'='true');


--2、导入数据到student_trans中
insert overwrite table student_trans
select sno,sname,sdept
from student;

select *
from student_trans;

--3、对student_trans建立聚合物化视图
CREATE MATERIALIZED VIEW student_trans_agg
AS SELECT sdept, count(*) as sdept_cnt from student_trans group by sdept;

--注意 这里当执行CREATE MATERIALIZED VIEW,会启动一个MR对物化视图进行构建
--可以发现当下的数据库中有了一个物化视图
show tables;
show materialized views;

--4、对原始表student_trans查询
--由于会命中物化视图,重写query查询物化视图,查询速度会加快(没有启动MR,只是普通的table scan)
SELECT sdept, count(*) as sdept_cnt from student_trans group by sdept;

--5、查询执行计划可以发现 查询被自动重写为TableScan alias: itcast.student_trans_agg
--转换成了对物化视图的查询 提高了查询效率
explain SELECT sdept, count(*) as sdept_cnt from student_trans group by sdept;

Hive 物化视图
https://flepeng.github.io/045-Hive-21-命令-Hive-物化视图/
作者
Lepeng
发布于
2025年1月21日
许可协议