
# HTAP
#### 简介
HTAP（Hybrid Transactional/Analytical Processing，混合事务分析处理）数据库架构是一种突破传统的处理事务型工作负载（OLTP）与分析型工作负载（OLAP）系统分离模式的技术创新方案。该架构通过统一数据存储引擎和计算资源调度机制，实现OLTP与OLAP在同一个技术架构内的协同运作，有效消除传统架构因数据冗余、延迟同步和资源隔离导致的分析效率低下问题，为实时决策支持提供统一数据基础设施。
GaussDB HTAP架构创新性地在传统行存引擎与执行引擎基础上，深度融合IMCV （In-memory Column View ，列式内存引擎）、混合负载透明路由机制以及向量化执行引擎，构建完整的行列混存技术体系。该架构通过SQL级数据迁移接口实现行存数据向IMCV的实时转换，依托内存持久化技术保障TP/AP操作的数据强一致性，有效解决传统行列混合架构的数据同步延迟问题。其核心突破在于：基于多维度代价模型的智能路由引擎可实时解析混合负载特征，自动将OLTP请求定向至行存引擎保障事务性能，同时将复杂分析查询精准路由至IMCV引擎实现性能的有效提升，最终通过统一SQL接口对外提供无感知的实时分析能力。
![](https://support.huaweicloud.com/distributed-devg-v10-gaussdb/public_sys-resources/note_3.0-zh-cn.png)
当前HTAP仅支持Ustore存储引擎。
#### 示例
本节以完整的执行流程为例，介绍如何使用HTAP混合负载查询。
1. 开启HTAP功能并设置相关参数。具体操作请参见《最佳实践》中"HTAP最佳实践 \> 前置准备"章节。 
   分布式下HTAP仅支持ORA兼容性，因此创建ORA兼容性数据库，后续步骤中所有操作均在该数据库下进行。
   ```
   htapdb=# CREATE DATABASE htapdb WITH DBCOMPATIBILITY='ORA';
   CREATE DATABASE
   htapdb=# \c htapdb
   Non-SSL connection (SSL connection is recommended when requiring high-security)
   You are now connected to database "htapdb" as user "xxx".
   ```
   
   
2. 执行HTAP DDL，创建IMCV元数据并将行存数据加载至IMCV。
   
   - 通过ALTER方式，对已经存在的表创建IMCV。
     ```
     --场景1：
     --已经存在的普通表全部列创建IMCV。
     htapdb=# DROP TABLE IF EXISTS htap_test;
     NOTICE:  table "htap_test" does not exist, skipping
     DROP TABLE
     htapdb=# CREATE TABLE htap_test(id int, dept_id int, salary int, name varchar(20), comments varchar(20)) WITH (storage_type = ustore);
     CREATE TABLE
     htapdb=# INSERT INTO htap_test VALUES (generate_series(1,3000), 1, 1000, 'large', 'large table');
     INSERT 0 3000
     htapdb=# ALTER TABLE htap_test COLVIEW;
     ALTER TABLE
     --场景2：
     --已经存在的普通表指定字段创建IMCV。
     htapdb=# DROP TABLE IF EXISTS htap_test;
     DROP TABLE
     htapdb=# CREATE TABLE htap_test(id int, dept_id int, salary int, name varchar(20), comments varchar(20)) WITH (storage_type = ustore);
     CREATE TABLE
     htapdb=# INSERT INTO htap_test VALUES (generate_series(1,3000), 1, 1000, 'large', 'large table');
     INSERT 0 3000
     htapdb=# ALTER TABLE htap_test COLVIEW(id, dept_id, salary);
     ALTER TABLE
     --场景3：
     --已经存在的分区表指定分区创建IMCV。
     htapdb=# DROP TABLE IF EXISTS htap_test;
     DROP TABLE
     htapdb=# CREATE TABLE htap_test(id int, dept_id int, salary int, name varchar(20), comments varchar(20)) WITH (storage_type = ustore)
     PARTITION BY RANGE(id)
     (
     PARTITION p1 VALUES LESS THAN (1001),
     PARTITION p2 VALUES LESS THAN (2001),
     PARTITION p3 VALUES LESS THAN (3001)
     );
     CREATE TABLE
     htapdb=# INSERT INTO htap_test VALUES (generate_series(1,3000), 1, 1000, 'large', 'large table');
     INSERT 0 3000
     --仅指定分区p1创建IMCV。
     htapdb=# ALTER TABLE htap_test MODIFY PARTITION p1 COLVIEW;
     ALTER TABLE
     ```
     
   
   - 通过CREATE方式，在创建表时创建IMCV。
     ```
     --场景1：
     --建表时全部字段创建IMCV。
     htapdb=# DROP TABLE IF EXISTS htap_test;
     DROP TABLE
     htapdb=# CREATE TABLE htap_test(id int, dept_id int, salary int, name varchar(20), comments varchar(20)) COLVIEW WITH (storage_type = ustore);
     CREATE TABLE
     --场景2：
     --建表时指定字段创建IMCV。
     htapdb=# DROP TABLE IF EXISTS htap_test;
     DROP TABLE
     --指定加载(id, dept_id, name)。
     htapdb=# CREATE TABLE htap_test(id int, dept_id int, salary int, name varchar(20) NOCOLVIEW, comments varchar(20) NOCOLVIEW) COLVIEW WITH (storage_type = ustore);
     CREATE TABLE
     --场景3：
     --建表时指定分区创建IMCV。
     htapdb=# DROP TABLE IF EXISTS htap_test;
     DROP TABLE
     htapdb=# CREATE TABLE htap_test(id int, dept_id int, salary int, name varchar(20), comments varchar(20)) COLVIEW WITH (storage_type = ustore)
     PARTITION BY RANGE(id)
     (
     PARTITION p1 VALUES LESS THAN (1001),
     PARTITION p2 VALUES LESS THAN (2001) NOCOLVIEW,
     PARTITION p3 VALUES LESS THAN (3001) NOCOLVIEW
     );
     CREATE TABLE
     ```
     
   
   
   
   
3. 查看创建IMCV的表的基本信息。 
   ```
   htapdb=# SELECT reloid,relname,imcvnattr,imcvkey FROM gs_imcv;
    reloid |  relname  | imcvnattr | imcvkey 
   --------+-----------+-----------+---------
     33248 | htap_test |         3 | 1 2 3
   (1 row)
   -- 通过gs_htap_imcv_info()函数查询表的基本信息，包含已加载的行组数、列存数据量等。
   htapdb=# SELECT * FROM gs_htap_imcv_info();
    rel_name  | partition_name | subpartition_name | schema_name | user_name | imcvnattr | imcvkey | priority | rowgroup_num | populated_rowgroup_num | cu_num_in_
   mem | cu_mem_size | cu_num_in_disk | cu_disk_size 
   -----------+----------------+-------------------+-------------+-----------+-----------+---------+----------+--------------+------------------------+-----------
   ----+-------------+----------------+--------------
    htap_test |                |                   | public      | ****      |         3 | 1 2 3   |        1 |            0 |                      0 |           
     0 |           0 |              0 |            0
   (1 row)
   ```
   
   
4. 执行查询，根据业务负载特征，准确路由至行存/列存引擎。 
   ```
   --自动透明路由模式：根据相关表、列是否加载列存以及判断行存/列存计划代价的高低，自动选择行存、列存以及行列混合执行计划。
   htapdb=# SET htap_router_mode='auto';
   SET
   htapdb=# EXPLAIN (COSTS OFF) SELECT id,dept_id FROM htap_test; --列存计划代价更低，选择列存计划。
                 QUERY PLAN               
   ---------------------------------------
    Row Adapter
      ->  Vector Streaming (type: GATHER)
            Node/s: All datanodes
            ->  Imcv Scan on htap_test
   (4 rows)
   htapdb=# EXPLAIN (COSTS OFF) SELECT * FROM htap_test; --加载列未覆盖查询要求，选择行存计划。
            QUERY PLAN          
   -----------------------------
    Streaming (type: GATHER)
      Node/s: All datanodes
      ->  Seq Scan on htap_test
   (3 rows)
   --强制列存模式：当查询相关表和列存在列存加速时，自动执行列存计划，若表不存在列存加速或者加载列未覆盖查询要求，则执行行存计划。
   htapdb=# SET htap_router_mode='column';
   SET
   htapdb=# EXPLAIN (COSTS OFF) SELECT id,dept_id FROM htap_test; --强制执行列存计划。
                 QUERY PLAN               
   ---------------------------------------
    Row Adapter
      ->  Vector Streaming (type: GATHER)
            Node/s: All datanodes
            ->  Imcv Scan on htap_test
   (4 rows)
   htapdb=# EXPLAIN (COSTS OFF) SELECT * FROM htap_test; --加载列未覆盖查询要求，选择执行行存计划。
            QUERY PLAN          
   -----------------------------
    Streaming (type: GATHER)
      Node/s: All datanodes
      ->  Seq Scan on htap_test
   (3 rows)
   --强制行存模式：无论是否加载HTAP列存，对于查询负载均选择执行行存计划。
   htapdb=# SET htap_router_mode='row';
   SET
   htapdb=# EXPLAIN (COSTS OFF) SELECT id,dept_id FROM htap_test; --强制执行行存计划。
            QUERY PLAN          
   -----------------------------
    Streaming (type: GATHER)
      Node/s: All datanodes
      ->  Seq Scan on htap_test
   (3 rows)
   ```
   
   
5. 【可选】卸载IMCV。 
   ```
   --卸载IMCV表。卸载IMCV后，需要重新执行步骤2，才能继续使用HTAP功能。
   htapdb=# ALTER TABLE htap_test NOCOLVIEW;
   ALTER TABLE
   htapdb=# SELECT * FROM gs_htap_imcv_info();
    rel_name | partition_name | subpartition_name | schema_name | user_name | imcvnattr | imcvkey | priority | rowgroup_num | populated_rowgroup_num | cu_num_in_mem | 
   cu_mem_size | cu_num_in_disk | cu_disk_size 
   ----------+----------------+-------------------+-------------+-----------+-----------+---------+----------+--------------+------------------------+---------------+-
   ------------+----------------+--------------
   (0 rows)
   ```
   
   
 
