GaussDB临时表介绍系列 - 全局临时表
GaussDB临时表介绍系列 - 全局临时表
当前GaussDB(DWS)支持多种临时表功能。本篇文章介绍全局临时表功能与基本用法。
全局临时表与本地临时表和volatile临时表区别是表定义在多个会话间共享,不用每个会话都创建临时表。
1. 前言
全局临时表特点:
-
表定义是全局的, 所有会话共享全局临时比表的表定义。元数据会持久化到系统表。
-
数据是会话相关的,其他会话看不到本会话导入的数据。
2. 全局临时表语法
CREATE GLOBAL { TEMPORARY | TEMP } TABLE [ IF NOT EXISTS ] table_name
({ column_name data_type [ compress_mode ] [ COLLATE collation ] [ column_constraint [ ... ] ]
| table_constraint
| LIKE source_table [ like_option [...] ] }
[, ... ])
[ WITH ( {storage_parameter = value} [, ... ] ) ]
[ ON COMMIT { PRESERVE ROWS } ]
建表时需要指定GLOBAL TEMP或者GLOBAL TEMPORARY,表示创建全局临时表。
- ON COMMIT { PRESERVE ROWS }
ON COMMIT PRESERVE ROWS 选项决定在事务中执行临时表的数据更新,当事务提交时,此临时表在事务中的更新会提交。
不支持其他ON COMMIT 类型。
3. 使用场景
在业务中多个会话都会临时表进行数据的加工。多个会话的表定义相同。复杂业务封装在视图中,视图使用临时表进行数据的轮转和加工。不同会话都会调用这个视图。如果这个临时表是本地临时表,那每个会话都需要创建和删除或者TRUNCATE临时表。每次调用视图都需要创建临时表,效率较低。
这种场景下,可以尝试使用全局临时表。业务中提前好全局临时表,视图中只需关心业务逻辑比如查询或者数据的导入。
4. 全局临时表DDL
会话1创建全局临时表
gaussdb =# create global temp table gtt1(a int,b int) ;
NOTICE: The 'DISTRIBUTE BY' clause is not specified. Using round-robin as the distribution mode by default.
HINT: Please use 'DISTRIBUTE BY' clause to specify suitable data distribution column.
CREATE TABLE
会话2可以查询到这张临时表
gaussdb=# select * from gtt1;
a | b
---+---
(0 rows)
全局临时表的relpersistence 是‘g’。
gaussdb=# select relname, relpersistence from pg_class where relname = 'gtt1';
relname | relpersistence
---------+----------------
gtt1 | g
(1 row)
会话1插入数据
gaussdb=# insert into gtt1 values(1,1),(2,2);
INSERT 0 2
会话2删除表失败。 需要等所有会话都解绑(参见第5部分解释)此张全局临时表才能进行表定义的修改。
gaussdb=# drop table gtt1;
ERROR: can not DROP TABLE when global temp table "gtt1" is in use
使用DISCARD GLOBAL TEMP
命令释放与全局临时表相关的会话资源,与会话解绑。
gaussdb=# discard global temp table gtt1; -- 会话1
DISCARD GLOBAL TEMP
会话2删除表成功
gaussdb=# drop table gtt1;
DROP TABLE
在有会话绑定时可以进行的表修改操作:
RENAME
、ALTER TABLE RENAME
、COMMENT
、ALTER TABLE COMMENT
5. 全局临时表DML
在会话有数据插入(Insert/Upsert/Merge/Copy等)时,称全局临时表绑定了当前会话。
两个会话并发进行操作,都只能查出自己会话导入的数据,不能查出其他会话的数据。
会话1
gaussdb=# insert into gtt1 values(1,1),(2,2);
INSERT 0 2
gaussdb=# select *from gtt1;
a | b
---+---
1 | 1
2 | 2
(2 rows)
会话2
gaussdb=# insert into gtt1 values(3,3),(4,4),(5,5);
INSERT 0 2
gaussdb=# select *from gtt1;
a | b
---+---
3 | 3
4 | 4
5 | 5
(3 rows)
多个会话对同一张全局临时表可以并发analyze、truncate。并且只对当前会话的数据进行操作。
会话1
gaussdb=# select count(*) from gtt1 group by b; -- 触发runtime analyze
gaussdb=# select tablename, attname, histogram_bounds FROM pg_stats where tablename = 'gtt1';
tablename | attname | histogram_bounds
-----------+---------+------------------
gtt1 | a | {1,2}
gtt1 | b | {1,2}
(2 rows)
会话2
gaussdb=# select count(*) from gtt1 group by b;
count
-------
1
1
1
(3 rows)
gaussdb=# select tablename, attname, histogram_bounds FROM pg_stats where tablename = 'gtt1';
tablename | attname | histogram_bounds
-----------+---------+------------------
gtt1 | a | {3,4,5}
gtt1 | b | {3,4,5}
(2 rows)
可见每个会话都会根据自己会话的数据收集统计信息。
6. 三种临时表对比
本地临时表 | volatile临时表 | 全局临时表 | |
---|---|---|---|
表定义 | 会话独立 | 会话独立 | 会话共享 |
元数据 | 持久化 | 不持久化 | 持久化 |
CN Retry | 支持 | 不支持 | 支持 |
DML | 会话独立 | 会话独立 | 会话独立 |
DDL | 范围最广 | 不支持ALTER/GRANT | 需会话解绑后才能进行DDL |
使用场景 | 业务没有重试机制,依赖CN Retry | 频繁创建表且不希望系统表膨胀 | 多会话共享表定义 |
7. 使用约束
- 需要等待全局临时表的所有会话都退出或者解绑才能进行表定义修改。建议不要频繁更新全局临时表的表结构。
- 不支持 on commit delete。
- 不支持分区表、delta表、hstore表。
- 点赞
- 收藏
- 关注作者
评论(0)