更新时间:2026-07-28 GMT+08:00
分享

混合负载透明路由

混合查询负载支持多种路由模式:自动路由、强制列存、强制行存,通过设置htap_router_mode='auto'、'column'、'row'来选择。

数据准备

创建一个包含几行数据的小表(test_small)以及包含3千行数据的大表(test_large)并插入数据。小表执行行存扫描更快,大表执行列存扫描更快。

示例:

gaussdb=# CREATE TABLE test_small (
                             id int,
                             dept_id int,
                             salary int,
                             name varchar(20),
                             comments varchar(30));
CREATE TABLE
gaussdb=# INSERT INTO test_small VALUES (1, 1, 1000, 'Jack', 'AAAA');
INSERT 0 1
gaussdb=# INSERT INTO test_small VALUES (2, 4, 2000, 'Sam', 'BBBB');
INSERT 0 1
gaussdb=# INSERT INTO test_small VALUES (3, 2, 3000, 'Sara', 'CCCC');
INSERT 0 1
gaussdb=# INSERT INTO test_small VALUES (4, 6, 4000, 'Oulu', 'DDDD');
INSERT 0 1
gaussdb=# INSERT INTO test_small VALUES (5, 3, 5000, 'John', 'EEEE');
INSERT 0 1
gaussdb=# CREATE TABLE test_large (
                             id int,
                             dept_id int,
                             salary int,
                             name varchar(20),
                             comments varchar(30));
CREATE TABLE
gaussdb=# INSERT INTO test_large VALUES (generate_series(1,15000), 1, 1000, 'large', 'large table');
INSERT 0 15000
--对表test_small加速全部列。
gaussdb=# ALTER TABLE test_small COLVIEW;
ALTER TABLE
--对表test_large加速部分列。
gaussdb=# ALTER TABLE test_large COLVIEW(id, dept_id, salary);
ALTER TABLE

自动路由模式

通过设置htap_router_mode的值为'auto',可开启自动路由模式。自动路由模式可根据相关表、列是否创建IMCV,以及行列计划代价高低,自动选择行、列、行列混合执行计划。

示例:

gaussdb=# SET htap_router_mode = 'auto';
SET
gaussdb=# SHOW htap_router_mode;
 htap_router_mode
------------------
 auto
(1 row)

--行存计划代价更低,选择行存计划。
gaussdb=# EXPLAIN (COSTS OFF) SELECT * FROM test_small;
       QUERY PLAN
------------------------
 Seq Scan on test_small
(1 row)

--列存计划代价更低,选择列存计划。
gaussdb=# EXPLAIN (COSTS OFF) SELECT id,dept_id FROM test_large;
          QUERY PLAN
-------------------------------
 Row Adapter
   ->  Imcv Scan on test_large
(2 rows)

--加速列不满足查询需求,选择行存计划。
gaussdb=# EXPLAIN (COSTS OFF) SELECT * FROM test_large;
       QUERY PLAN
------------------------
 Seq Scan on test_large
(1 row)

强制列存模式

以AP型负载为主的情况下,可通过设置htap_router_mode的值为'column',打开强制列存模式。该模式下,当查询相关表和列存在IMCV时,在满足列存查询的条件下,将无视代价高低,优先选择列存执行计划。

示例:

gaussdb=# SET htap_router_mode = 'column';
SET
gaussdb=# SHOW htap_router_mode;
 htap_router_mode
------------------
 column
(1 row)

--表中所有列均创建IMCV,执行列存计划。
gaussdb=# EXPLAIN (COSTS OFF) SELECT * FROM test_small;
          QUERY PLAN
-------------------------------
 Row Adapter
   ->  Imcv Scan on test_small
(2 rows)

--查询目标列创建IMCV,执行列存计划。
gaussdb=# EXPLAIN (COSTS OFF) SELECT id,dept_id FROM test_large;
          QUERY PLAN
-------------------------------
 Row Adapter
   ->  Imcv Scan on test_large
(2 rows)

--查询目标列未创建IMCV,执行行存扫描row2col转向量化。
gaussdb=# EXPLAIN (COSTS OFF) SELECT * FROM test_large;
               QUERY PLAN
----------------------------------------
 Row Adapter
   ->  Vector Adapter(type: BATCH MODE)
         ->  Seq Scan on test_large
(3 rows)

强制行存模式

以TP型负载为主的情况下,可通过设置htap_router_mode的值为'row',打开强制行存模式。该模式下,无论是否满足列存执行计划的条件,均选择行存计划。

示例:

gaussdb=# SET htap_router_mode = 'row';
SET
gaussdb=# SHOW htap_router_mode;
 htap_router_mode
------------------
 row
(1 row)

--强制执行行存计划。
gaussdb=# EXPLAIN (COSTS OFF) SELECT * FROM test_small;
       QUERY PLAN
------------------------
 Seq Scan on test_small
(1 row)

--强制执行行存计划。
gaussdb=# EXPLAIN (COSTS OFF) SELECT id,dept_id FROM test_large;
       QUERY PLAN
------------------------
 Seq Scan on test_large
(1 row)

--强制执行行存计划。
gaussdb=# EXPLAIN (COSTS OFF) SELECT * FROM test_large;
       QUERY PLAN
------------------------
 Seq Scan on test_large
(1 row)

Hint指定路由模式

单条查询可使用Hint指定目标表的列存扫描执行计划,即当指定表存在列存并且加载列满足查询要求时,强制该表执行列存扫描。例如,基于Hint语法“/* + imcvscan (tbl) */” 实现。

示例:

gaussdb=# SET htap_router_mode = 'row';
SET
gaussdb=# SHOW htap_router_mode;
 htap_router_mode
------------------
 row
(1 row)

--虽然行存计划代价更低,但基于Hint选择列存计划。
gaussdb=# EXPLAIN (COSTS OFF) SELECT /*+imcvscan (test_small)*/ * FROM test_small;
          QUERY PLAN
-------------------------------
 Row Adapter
   ->  Imcv Scan on test_small
(2 rows)

--基于Hint强制选择列存计划。
gaussdb=# EXPLAIN (COSTS OFF) SELECT /*+imcvscan (test_large)*/ id,dept_id FROM test_large;
          QUERY PLAN
-------------------------------
 Row Adapter
   ->  Imcv Scan on test_large
(2 rows)

--Hint指定表加速列不满足查询需求,选择行存计划。
gaussdb=# EXPLAIN (COSTS OFF) SELECT /*+imcvscan (test_large)*/ * FROM test_large;
WARNING:  unused hint: ImcvScan(test_large)
       QUERY PLAN
------------------------
 Seq Scan on test_large
(1 row)

--Hint指定test_large执行列存扫描。
gaussdb=# EXPLAIN (COSTS OFF) SELECT /*+imcvscan (test_large)*/ test_small.id, test_large.dept_id FROM test_small, test_large WHERE test_small.id = test_large.id;
                     QUERY PLAN
----------------------------------------------------
 Row Adapter
   ->  Vector Sonic Hash Join
         Hash Cond: (test_large.id = test_small.id)
         ->  Imcv Scan on test_large
         ->  Vector Adapter(type: BATCH MODE)
               ->  Seq Scan on test_small
(6 rows)

--Hint指定连接两表均执行列存扫描。
gaussdb=# EXPLAIN (COSTS OFF) SELECT /*+imcvscan (test_large) imcvscan (test_small)*/ test_small.id, test_large.dept_id FROM test_small, test_large WHERE test_small.id = test_large.id;
                     QUERY PLAN
----------------------------------------------------
 Row Adapter
   ->  Vector Sonic Hash Join
         Hash Cond: (test_large.id = test_small.id)
         ->  Imcv Scan on test_large
         ->  Imcv Scan on test_small
(5 rows)

gaussdb=# DROP TABLE test_small;
DROP TABLE

gaussdb=# DROP TABLE test_large;
DROP TABLE

相关文档