# 物化视图概述
物化视图（Materialized View）是一种特殊的数据库对象。它将复杂计算的查询结果预先进行计算并持久化到存储介质中，业务查询时直接查询已经预计算好的数据，最终实现加速查询的目的。
![](https://support.huaweicloud.com/devg-911-dws/figure/zh-cn_image_0000002662075287.png "点击放大")
物化视图主要有两大核心应用场景：透明加速和动态数据流。
表1物化视图两大核心应用场景 
| 场景    | 说明                    | 典型用例           |
|:---|:---|:---|
| 透明加速 | 查询自动重写为物化视图，无需修改业务  | 报表加速、仪表盘         |
| 动态数据流 | 分层物化视图，通过增量计算实现实时数据流动 | 数仓分层(DWD→DWS→ADS) |
   
#### 物化视图中的基本概念
物化视图中的基本概念解释如下表：
表2物化视图基本概念 
| 概念    | 说明                                                                                                                                                                                                                                                                                                                                                                                                                                          |
|:---|:---|
| 基表   | 物化视图定义中所依赖的表，支持DWS 内表、外表、分区表、视图或物化视图，不支持临时表。                                                                                                                                                                                                                                                                                                                                                                                                   |
| 失效    | 基表发生数据变化后，物化视图会被标记成失效状态。可直接查询，不能自动重写。                                                                                                                                                                                                                                                                                                                                                                                                         |
| 刷新      | 创建物化视图后，物化视图中存储的数据只反映创建时刻的状态。当基表中的数据发生变化时，需要通过刷新物化视图更新数据变化。 根据刷新模式可划分为：全量刷新和增量刷新。 - 全量刷新：每次刷新重新计算物化视图中的数据。  - 增量刷新：每次刷新将基表自上次刷新后数据变更的部分刷新到物化视图。   |
| 透明加速 | 查询重写自动将SQL定向到物化视图，无需修改业务。                                                                                                                                                                                                                                                                                                                                                                                                                     |
| 动态数据流   | 分层嵌套创建多个物化视图，通过增量计算实现自底向上实时的动态数据流动。满足实时数仓的数据分层要求。                                                                                                                                                                                                                                                                                                                                                                                              |
   
#### 物化视图与普通视图及表的区别
- 普通视图是虚拟表，只存储视图的SQL定义，不存储查询结果的数据。在查询重写时会把对视图的查询转化为对基表的查询。
- 物化视图是实体表，既存储视图的SQL定义，也存储查询结果的数据。基表发生数据变化时，触发物化视图的失效。物化视图刷新时再重新计算为最新的数据。
查询重写时，根据用户SQL与物化视图SQL的匹配情况，选择直接从物化视图读取预计算的最新数据。
表3物化视图与普通视图及表的区别 
| 对比维度      | 物化视图  | 普通视图   | 普通表    |
|:---|:---|:---|:---|
| 数据存储     | ✓    | ✗       | ✓    |
| 索引支持      | ✓      | ✗    | ✓   |
| 查询性能提升   | ✓    | ✗    | ✗   |
| 空间占用       | ✓    | ✗      | ✓      |
| 数据一致性  | 需刷新 | 实时一致 | 实时一致 |
| 业务逻辑简化 | ✓   | ✓    | ✗  |
   
#### 物化视图的基本原理
1. 数据预计算：基于指定的基础查询语句（可包含关联、聚合、过滤等操作），在物化视图创建/刷新时，将查询结果一次性计算并存储为物理表，数据与基础表解耦。
2. 数据一致性：基础表数据发生变更（增删改）时，物化视图的预存数据会过期，需通过刷新机制同步基础表变化，平衡查询性能与数据实时性。
3. 透明加速：当用户SQL与物化视图SQL匹配时，查询重写会自动选择从物化视图读取数据。无需修改业务SQL，即可实现复杂查询的响应时间，降低系统负载。
简单来说，物化视图是"空间换时间"的典型优化方案，以额外的存储开销和少量的刷新性能损耗，换取复杂查询的毫秒级响应。
#### 异步物化视图和同步物化视图
创建物化视图后，当基表中的数据发生变化时，需要通过刷新物化视图更新数据变化。根据刷新方式，可分为异步物化视图和同步物化视图。
- 异步物化视图：基表数据变化后需要定期触发物化视图刷新，更新物化视图中数据。
  - 手动刷新：在业务数据修改后通过执行REFRESH MATERIALIZED VIEW 进行相应物化视图的刷新。
  
  - 自动刷新：在物化视图创建时指定刷新开始时间和刷新间隔。由数据库负责定期刷新。
   
- 同步物化视图：基表数据变化后物化视图数据自动变化。通过CREATE MATERIALIZED VIEW语法的以下两个参数设置：
  - ON COMMIT：基表修改的事务提交时，会触发基表上所有物化视图刷新。保证了基表与物化视图的数据强一致性。
  
  - ON STATEMENT：基表修改的DML语句执行时，触发基表上所有物化视图刷新。保证了基表与物化视图的数据强一致性。
   
 
表4异步物化视图和同步物化视图区别 
| 对比维度    | 异步物化视图        | 同步物化视图          |
|:---|:---|:---|
| 触发刷新时机   | 手动或定时轮询      | 基表发生数据修改时      |
| 对基表影响   | 无影响        | 拖慢基表入库性能        |
| 触发失效情况 | 基表写入后，物化视图失效 | 数据严格一致，物化视图不失效 |
| 适用场景  | 批量更新或微批更新     | 严格要求实时一致的场景     |
   
#### 物化视图的优势
- **声明式编程**
  用一条SQL实现数据的搬运，不再需要编写复杂的存储过程来实现两张表直接的数据搬运。索引、锁、数据一致性都自动考虑，对业务影响小。
  
- **灵活刷新**
  刷新方式：支持全量刷新和增量刷新。
  刷新模式：支持手动刷新，定时刷新和同步实时刷新。还支持按嵌套的链路级联刷新。
  
- **流式加工**
  将数仓的DWD（Data Warehouse Detail，明细层，负责清洗去重标准化原始数据）\>DWB（Data Warehouse Base，基础层，整合关联宽表化）\>DWS（Data WareHouse Service：汇总层，常用聚合指标）\>ADS（Application Data Store，应用层，例如具体报表）都创建为物化视图。通过增量计算实现实时的数据流式动态加工。
  
- **透明加速**
  物化视图预先计算并存储查询结果，当发起查询时，可以查询物化视图直接返回结果，从而提高查询性能，且无需修改业务。
  

- **增效降本**
  多次执行复杂查询通常需要显著的CPU和内存资源。物化视图通过透明加速将复杂的重复计算重写为简单的查询物化视图的SQL，可显著降低集群负载。
  

- **瞬时物化**
  将物化视图进行分区，使用通用的分区自动管理功能，实现旧分区的自动淘汰，可减轻数据管理的负担。
  
- **冷热分仓**
  将物化视图进行分区，使用通用的分区自动转冷功能，实现旧分区的自动转冷。可自动降低存储成本。
  
 
#### 物化视图相关语法
前提条件：
DWS的物化视图特性仅8.2.1.220及以上集群支持，使用物化视图需确保[enable_matview](https://support.huaweicloud.com/devg-911-dws/dws_04_0931.html#ZH-CN_TOPIC_0000002166614152__section17297153214352)设置为on。
- 创建物化视图。
  ```
  CREATE MATERIALIZED VIEW [ IF NOT EXISTS ] materialized_view_name
  [ ( column_name [, ...] ) ]
  [ BUILD { DEFERRED | IMMEDIATE } ]
  [ REFRESH [ [ DEFAULT ] | [ RESTRICT ] | [ CASCADE FORWARD ] | [ CASCADE BACKWARD ] | [ CASCADE ALL ] ]
            [ COMPLETE | FAST ]
            [ [ ON DEMAND ] | [ ON STATEMENT ] | [ ON COMMIT ] ]
            [ [ START WITH (timestamptz) ] | [ EVERY (interval) ] ] ]
  [ { ENABLE | DISABLE } QUERY REWRITE ]
  [ WITH ( {storage_parameter = value} [, ... ] ) ]
  [ TABLESPACE tablespace_name ]
  [ DISTRIBUTE BY { REPLICATION | ROUNDROBIN | { HASH ( column_name [,...] ) } } ]
  [ PARTITION BY {(column_name) | date_trunc('time_unit', column_name)} ]
  AS query;
  ```
  
![](https://support.huaweicloud.com/devg-911-dws/figure/zh-cn_image_0000002527845562.png "点击放大")
- 刷新物化视图。
  ```
  REFRESH MATERIALIZED VIEW
  {[schema.]materialized_view_name} [ [DEFAULT] | [ RESTRICT ] | [ CASCADE FORWARD ] | [ CASCADE BACKWARD ] | [ CASCADE ALL ] ]
  ```
  
- 删除物化视图。
  ```
  DROP MATERIALIZED VIEW [ IF EXISTS ]
  {[schema.]materialized_view_name} [, ...] [ CASCADE | RESTRICT ];
  ```
  
- 修改物化视图。
  ```
  ALTER MATERIALIZED VIEW [ IF EXISTS ] { materialized_view_name }[ ENABLE | DISABLE ] QUERY REWRITE;
  ALTER MATERIALIZED VIEW [ IF EXISTS ] { materialized_view_name }
      REFRESH [ [DEFAULT] | [ RESTRICT ] | [ CASCADE FORWARD ] | [ CASCADE BACKWARD ] | [ CASCADE ALL ] ] [ COMPLETE ] [ ON DEMAND ] [ [ START WITH (timestamptz) ] | [ EVERY (interval) ] ];
  ALTER MATERIALIZED VIEW [ IF EXISTS ] { materialized_view_name }
      REFRESH [DEFAULT] | [ RESTRICT ] | [ CASCADE FORWARD ] | [ CASCADE BACKWARD ] | [ CASCADE ALL ] ;
  ALTER MATERIALIZED VIEW { materialized_view_name }
      OWNER TO new_owner;
  ALTER MATERIALIZED VIEW { materialized_view_name }
      SET ( {storage_parameter = value} [, ... ] )
      | RESET ( storage_parameter [, ... ] );
  ```
  
物化视图语法具体参数说明请参考[CREATE MATERIALIZED VIEW](https://support.huaweicloud.com/sqlreference-911-dws/dws_06_0357.html)和[ALTER MATERIALIZED VIEW](https://support.huaweicloud.com/sqlreference-911-dws/dws_06_0358.html)章节。
#### 物化视图的应用场景
物化视图适用如下场景：
- 查询结果不经常改变，即基表稳定且执行频次高的查询。
- 查询包含非常耗时的操作，比如聚合、连接操作等。对于涉及多个表连接和聚合操作的查询，物化视图可以将这些耗时的操作预先计算并存储起来，从而避免在每次查询时都重新执行这些操作。
- 查询结果仅涉及表中的很小部分数据。
 
#### 使用物化视图所需操作权限
- 创建物化视图时需要schema的CREATE权限和基表或列的SELECT权限。
- 查询物化视图需要物化视图的SELECT权限。
- 刷新需要物化视图的INSERT、UPDATE、DELETE、ANALYZE权限和基表或列的SELECT权限。
- 删除物化视图需要有DROP TABLE的权限。
 
#### 物化视图使用限制
- 不支持包含临时表，包括全局临时表、volatile临时表和普通临时表。
- 不支持物化视图定义中的CTE包含除SELECT语句以外的其他DML。
- 不支持基表上存在脱敏策略和行级访问控制或者基表属于私有用户。脱敏策略和行级访问控制可能会导致结果集错误，而私有用户可能导致刷新物化视图失败等问题
- 9.1.0.200及以上版本支持stable和volatile函数。物化视图无法感知函数内容变化，如果需要函数变化及时反馈到物化视图结果中，需执行REFRESH MATERIALIZED VIEW RESTRICT进行物化视图刷新或者跟随数据更新反馈到物化视图。
- 物化视图无法自动感知影响其查询执行的全局变量或会话参数变更，需要再次刷新物化视图更新结果。
 
#### 物化视图使用建议
- 存储资源：物化视图会占用额外的存储空间，需要考虑磁盘容量。
- 刷新维护：自动或手动刷新物化视图会消耗系统资源，如果基础表数据变化频繁，刷新操作可能会影响系统性能。
- 数据一致性和实时性：异步物化视图中的数据可能不是实时的，即数据不会随着原始数据的更新而自动更新。如果基础表数据发生变化，视图中的数据可能会过时，需要定期刷新以保持数据一致性。
- 设计复杂性：物化视图的设计和创建需要仔细考虑预期的查询模式和数据访问模式，以便实现最佳的性能优化。
 
