【GaussDB】GaussDB 表的创建与使用之临时表

【摘要】

表是数据库对象基本单位,其由行、列构成二维表格,二维表也被称为关系(relation),关系数据库也可称为二维表数据库。关系型数据库中,数据的操作和管理都是围绕着表进行,GaussDB表有七种类型,分别为:普通表、临时表、非日志表、外表、分区表、列存表、物化视图。每种类型的表在使用业务场景上各不同。

1 问题现象

临时表(Temprorary Table)是一种特殊类型的表,用于存储临时的数据,这些数据在会话期间或事务期间是短暂的,通常用于存储中间计算结果临时数据处理复杂查询的分步结果。

临时表的优势:

• 短暂数据存储:用于存储临时数据,不会长期占用数据库存储空间。

• 性能优化:可用减少复杂查询的计算时间,提高查询性能。

• 方便数据处理:适用于需要多步骤处理的数据操作。

2 技术背景

GaussDB 临时表分为全局临时表(global temp table)和本地临时表(local temp table)

• 临时表只存在数据库会话session期间,在会话中被创建的临时表,在会话结束时临时表会自动被删除。

• 临时表只对当前其所处的会话可见。数据库多个session连接之间不能访问彼此创建的临时表(global temp table全局临时表除外)。

• 由于临时表生命周期始于会话中该表创建时,止于会话结束,并且普通临时表具备会话隔离性,故其常用于存储查询结果或处理中间结果数据,避免被子查询和复杂查询重复使用。

• 全局临时表的元数据对所有session可见,其session结束后元数据继续存在。但session之间的用户数据,索引和统计信息相互隔离,每个session只能看到和更改自己提交的数据。全局临时表创建时可指定非pg_temp_前缀的schema。全局临时表分两种模式

1、 基于会话级别的全局临时表(on commit preserve rows),当会话结束时自动清空用户数据。全局临时表是默认会话级

2、 基于事务级别的全局临时表(on commit delete rows),当执行commit或rollback时自动清空用户数据

全局临时表不支持以下场景

• 不支持创建全局临时SEQUENCE,各个会话的全局临时表使用共享的SEQUENCE,只能保证唯一性,不保证连续性。

• 不支持创建全局临时视图。

• 不支持创建分区表。

• 不支持创建Hash bucket表。

• 不支持扩展统计信息。

• 不支持ON COMMIT DROP属性。

注意

• 临时表只对当前会话可见,因此不支持与\parallel on并行执行一起使用。

• 临时表不支持主备切换。

• 全局临时表不响应自动清理,在长连接场景使用时尽量使用on commit delete rows的全局临时表,或定期手动执行VACUUM,否则可能导致clog日志不回收。

• 全局临时表功能可以通过设置GUC参数max_active_global_temporary_table控制是否启用。如果max_active_global_temporary_table=0,关闭全局临时表功能。

• 全局临时表的DDL只会影响当前会话的用户数据和索引。例如TRUNCATE、REINDEX、ANALYZE只对当前会话有效。

• ALTER/DROP全局临时表和索引,如果其它会话正在使用它,禁止操作(ALTER INDEX index_name REBUILD除外)。

• 本地临时表通过每个会话独立的以pg_temp开头的schema来保证只对当前会话可见,因此,不建议用户在日常操作中手动删除以pg_temp、pg_toast_temp开头的SCHEMA。

3 案例分析

3.1 创建本地临时表

sql 复制代码
--会话1:创建本地临时表,并写入数据
[omm@ecs-wal-test-0001 ~]$ gsql -d postgres -p 30100 -ar
gsql ((GaussDB Kernel 505.2.0.SPC0100 build 2450ca36) compiled at 2024-11-02 19:03:53 commit 9980 last mr 20502 release)
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type "help" for help.
gaussdb=# create local temp table temp1 (id int, name varchar);
CREATE TABLE
gaussdb=#
gaussdb=# insert into temp1 values(1, 'temp1');
INSERT 0 1
gaussdb=#
gaussdb=# select * from temp1;
id | name
----+-------
1 | temp1
(1 row)
gaussdb=#
--会话2:查询临时表时,表被隔离了。
[omm@ecs-wal-test-0001 ~]$ gsql -d postgres -p 30100 -ar
gsql ((GaussDB Kernel 505.2.0.SPC0100 build 2450ca36) compiled at 2024-11-02 19:03:53 commit 9980 last mr 20502 release)
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type "help" for help.
gaussdb=# select * from temp1;
ERROR: Relation "temp1" does not exist on dn_6001_6002_6003.

3.2 创建全局临时表

sql 复制代码
--会话1:执行创建全局临时表
[omm@ecs-wal-test-0001 ~]$ gsql -d postgres -p 30100 -ar
gsql ((GaussDB Kernel 505.2.0.SPC0100 build 2450ca36) compiled at 2024-11-02 19:03:53 commit 9980 last mr 20502 release)
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type "help" for help.
gaussdb=# create global temp table temp2 (id int, name varchar);
CREATE TABLE
gaussdb=# insert into temp2 values(1, 'temp2');
INSERT 0 1
gaussdb=# select * from temp2;
id | name
----+-------
1 | temp2
(1 row)
gaussdb=#
--会话2:查询全局临时表:可以查询,但是查询不了数据。
[omm@ecs-wal-test-0001 ~]$ gsql -d postgres -p 30100 -ar
gsql ((GaussDB Kernel 505.2.0.SPC0100 build 2450ca36) compiled at 2024-11-02 19:03:53 commit 9980 last mr 20502 release)
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type "help" for help.
gaussdb=# select * from temp2;
id | name
----+------
(0 rows)
gaussdb=#
--会话2:对全局临时表写入数据,并查询,只看到会话会写入的数据,会话1的数据是查询不到。
gaussdb=# insert into temp2 values(2, 'temp3');
INSERT 0 1
gaussdb=# select * from temp2;
id | name
----+-------
2 | temp3
(1 row)
gaussdb=#
--说明:全局临时表,只查询当前会话的数据,其它会话写入数据是被屏蔽的。

3.3 创建基于会话级的全局临时表

sql 复制代码
--会话1:创建全局会话级的全局临时表,并写入数据
[omm@ecs-wal-test-0001 ~]$ gsql -d postgres -p 30100 -ar
gsql ((GaussDB Kernel 505.2.0.SPC0100 build 2450ca36) compiled at 2024-11-02 19:03:53 commit 9980 last mr 20502 release)
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type "help" for help.
gaussdb=# create global temp table temp3 (id int, name varchar) on commit preserve rows;
CREATE TABLE
gaussdb=# insert into temp3 values(1, 'temp3');
INSERT 0 1
gaussdb=# select * from temp3;
id | name
----+-------
1 | temp3
(1 row)
--会话1:退出会话时,重新查询全局临时表tmp3,数据被清除。
gaussdb=# \q
[omm@ecs-wal-test-0001 ~]$ gsql -d postgres -p 30100 -ar
gsql ((GaussDB Kernel 505.2.0.SPC0100 build 2450ca36) compiled at 2024-11-02 19:03:53 commit 9980 last mr 20502 release)
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type "help" for help.
gaussdb=# select * from temp3;
id | name
----+------
(0 rows)
gaussdb=#

3.4 创建基于事务级别的全局临时表

sql 复制代码
--会话1:创建基于事务级别全局临时表,并写入数据,当提交时数据被删除
[omm@ecs-wal-test-0001 ~]$ gsql -d postgres -p 30100 -ar
gsql ((GaussDB Kernel 505.2.0.SPC0100 build 2450ca36) compiled at 2024-11-02 19:03:53 commit 9980 last mr 20502 release)
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type "help" for help.
gaussdb=#
gaussdb=#
gaussdb=# create global temp table temp4 (id int, name varchar) on commit delete rows;
CREATE TABLE
gaussdb=#
gaussdb=# begin;
BEGIN
gaussdb=# insert into temp4 values(1, 'temp4');
INSERT 0 1
gaussdb=# select * from temp4;
id | name
----+-------
1 | temp4
(1 row)
gaussdb=# commit;
COMMIT
gaussdb=# select * from temp4;
id | name
----+------
(0 rows)
gaussdb=#

3.5 修改临时表的表结构

sql 复制代码
[omm@ecs-wal-test-0001 ~]$ gsql -d postgres -p 30100 -ar
gsql ((GaussDB Kernel 505.2.0.SPC0100 build 2450ca36) compiled at 2024-11-02 19:03:53 commit 9980 last mr 20502 release)
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type "help" for help.
gaussdb=# create local temp table temp1 (id int, name varchar);
CREATE TABLE
gaussdb=# insert into temp1 values(1, 'temp1');
INSERT 0 1
gaussdb=#
gaussdb=# alter table temp1 drop name;
ALTER TABLE
gaussdb=# select * from temp1;
id
----
1
(1 row)
gaussdb=# alter table temp2 add score int after id;
ALTER TABLE
gaussdb=# insert into temp2 values(2, 100, 'temp2');
INSERT 0 1
gaussdb=# select * from temp2;
id | score | name
----+-------+-------
2 | 100 | temp2
(1 row)
gaussdb=#

4 与全局临时表相关的GUC参数

|-----------------------------------|---------------------------------------------------------------------------------------|-------------------------------------------|------------------------------------------------------|
| G UC 参数名 | 参数说明 | 取值范围 | 默认值 |
| max_active_global_temporary_table | 全局临时表功能开关,控制是否可以创建全局临时表。该参数的取值决定了共享缓存中预留给全局临时表所需的哈希表的内存使用,并不会强制限制所有会话中的活跃全局临时表总数。 | 0 ~ 1000000 0:全局临时表功能关闭。 > 0:全局临时表功能打开。 | 1000 设置建议:推荐使用默认值 |
| vacuum_gtt_defer_check_age | vacuum执行后检查全局临时表relfrozenxid与普通表的差异。如果全局临时表relfrozenxid落后超过指定参数值,就会产生告警。该参数可在PDB级别设置。 | 0 ~ 1000000 | 10000 在PDB场景内,若未设置该参数,则继承来自全局的设置 设置建议:建议设置为默认值,不做调整。 |
| enable_gtt_concurrent_truncate | 是否支持全局临时表truncate table和DML的并发执行,以及全局临时表truncate table和truncate table的并发执行 | on:表示支持上述操作并发。 off:表示不支持上述操作并发。 | On 设置建议:建议设置为默认值,不做调整。 |

5 简单总结

临时表在应用开发中会经常使用。通常用于存储中间计算结果临时数据处理复杂查询的分步结果,隔离会话级别的数据访问。

转载:华为云论坛

相关推荐
RestCloud2 小时前
Oracle CDC实战:如何构建企业级实时数据同步架构
数据库·oracle·etl·etlcloud·数据同步·数据集成平台
dgfhf2 小时前
使用Python处理计算机图形学(PIL/Pillow)
jvm·数据库·python
૮・ﻌ・2 小时前
Node.js - 04:MongoDB、会话控制
数据库·mongodb·node.js·jwt·token·cookie·session
闻哥2 小时前
MySQL三大日志深度解析:redo log、undo log、binlog 原理与实战
android·java·jvm·数据库·mysql·adb·面试
头发长了2 小时前
在 VS2022 中创建 Qt C++ 项目并配置 OpenSceneGraph 3.6.5,进行三维模型开发
数据库·c++·qt
xcLeigh2 小时前
SQL 注入防不住?金仓内核级防火墙,白名单防护零误报
数据库·数据安全·sql注入·kingbasees·金仓数据库·数据补丁
轩情吖2 小时前
MySQL之复合查询
android·数据库·mysql·多表·符合查询·自连接·合并查询
Predestination王瀞潞2 小时前
2.3 依赖管理Maven工具->dependency详解:JUnit 3.8.1 vs 4.12
数据库·junit
FirstFrost --sy2 小时前
MySQL表的增删查改
数据库·mysql