混合负载透明路由
混合查询负载支持多种路由模式:自动路由、强制列存、强制行存,通过设置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