本文分享自华为云社区《GaussDB(DWS)临时表小结》,作者: sincatter 。
如下为创建表的基本语法(详见手册):
CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] 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 | DELETE ROWS | DROP } ]
[ COMPRESS | NOCOMPRESS ]
[ TABLESPACE tablespace_name ]
[ DISTRIBUTE BY { REPLICATION | { HASH ( column_name [,...] ) } } ]
[ TO { GROUP groupname | NODE ( nodename [, ... ] ) } ];
其中临时表相关的关键字有:
创建临时表时可以在TEMP或TEMPORARY前指定GLOBAL或LOCAL关键字。目前GaussDB(DWS)设立这两个关键字,仅仅是为了兼容SQL标准,实际行为上无论指定的是GLOBAL还是LOCAL,GaussDB(DWS)都只会创建为本地临时表,即只有LOCAL关键字是有效的。
TEMP和TEMPORARY等价。如果指定TEMP或TEMPORARY关键字,则创建的表为临时表。临时表行为上的主要特征为只在当前会话可见,本会话结束后会自动删除。由于临时表只在当前会话创建,对于涉及对临时表操作的DDL语句,很容易产生DDL失败的报错。因此,建议DDL语句中不要对临时表进行操作。
ON COMMIT选项决定在事务中执行创建临时表操作,当事务提交时,此临时表的后续操作。有以下三个选项:
GaussDB(DWS)的临时表机制继承自PostgreSQL,临时表在元数据和数据存储上与普通表基本无差异,具体来说,临时表是通过建表时将其Schema指定为与session id相关的一个schema,其他session实际上也是可以在系统表中查看到当前临时表的元数据。GaussDB(DWS)会利用schema进行临时表的不同session间隔离。这里通过两个现象去说明这个机制:
一个session_1创建一个临时表:
postgres=# create temp table tt1(a int);
CREATE TABLE
postgres=# \d
List of relations
Schema | Name | Type | Owner | Storage
------------------------------------------+------+-------+-------+----------------------------------
pg_temp_coordinator1_2_4_139820525504256 | tt1 | table | xucw | {orientation=row,compression=no}
(1 row)
postgres=# select relname,relnamespace from pg_class where relname like 'tt%';
relname | relnamespace
---------+--------------
tt1 | 24600
(1 row)
另外一个session_2,可以一样可以通过pg_class查看临时表的表结构:
postgres=# select relname,relnamespace from pg_class where relname like 'tt%';
relname | relnamespace
---------+--------------
tt1 | 24600
(1 row)
但session_2中是无法查看当前临时表中的数据:
postgres=# select * from pg_temp_coordinator1_2_4_139820525504256.tt1;
ERROR: Can only access temp objects of the current session.
LINE 1: select * from pg_temp_coordinator1_2_4_139820525504256.tt1;
创建一个临时表后,再根据这个临时表的schema,去创建一个相同schema的普通表:
postgres=# create temp table tt1(a int);
CREATE TABLE
postgres=# \d
List of relations
Schema | Name | Type | Owner | Storage
------------------------------------------+------+-------+-------+----------------------------------
pg_temp_coordinator1_2_3_139820525504256 | tt1 | table | xucw | {orientation=row,compression=no}
(1 row)
postgres=# create table pg_temp_coordinator1_2_3_139820525504256.tt2(a int);
CREATE TABLE
postgres=# select relname,relnamespace from pg_class where relname like 'tt%';
relname | relnamespace
---------+--------------
tt1 | 24592
tt2 | 24592
(2 rows)
随后,退出当前session,重新连接查看表状态,我们会神奇发现之前创建的临时表tt1消失的同时,创建的普通表tt2也一样消失了。
postgres=# select relname,relnamespace from pg_class where relname like 'tt%';
relname | relnamespace
---------+--------------
(0 rows)
临时表可以减少冗余中间表的存在,在一些复杂操作时,往往需要借助一些中间表去完成功能,但一般来说普通表的创建是需要数据库管理员来统计创建维护的。临时表的存在就允许中间表用完即清,减少数据库系统中冗余表的存在。另外,临时表在使用时数据是session间隔离的,其他session不能看到当前session的数据,数据安全性在一定程度上也更好。
对于过于复杂并且不易通过普通优化方法调整性能的SQL可以考虑拆分的方法,把SQL中某一部分拆分成独立的SQL并把执行结果存入临时表,拆分常见的场景包括但不限于:
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/devcloud/article/details/121747269
内容来源于网络,如有侵权,请联系作者删除!