我听说这两个术语“临时表”和“全局临时表”在类似的上下文中使用得非常相似。
两者有什么区别?
在 Oracle 中没有任何区别。当您在 Oracle 数据库中创建临时表时,它自动是全局的,您需要包含“全局”关键字。
SQL 标准定义了术语“GLOBAL TEMPORARY TABLE”的解释方式,允许使用 LOCAL 或 GLOBAL 范围。这将允许用户特定表 (LOCAL) 或每个人 (GLOBAL)。Oracle 仅实现 GLOBAL 版本。
您放入 Oracle 临时表的数据特定于您的会话。也就是说,即使有 100 个用户都在使用同一个表,也只有您可以看到您的数据,并且当您断开连接(或提交当前事务时)时,您的数据会从表中删除,具体取决于表设置。
将此与 MS SQL-Server 进行对比,其中临时表是本地的。如果您创建一个,除了您之外没有人知道您的临时表存在。在 Oracle 中,创建临时表允许每个人(以及有权访问您的模式的每个人)查看该表。当您注销会话时,SQL-Server 表将被删除,并且需要为下一个会话重新创建。在 Oracle 中,临时表现在是模式的永久部分,即使数据不是。
将此与 MS SQL-Server 进行对比,其中临时表是本地的。如果您创建一个,除了您之外没有人知道您的临时表存在。在 Oracle 中,创建临时表允许每个人(以及有权访问您的模式的每个人)查看该表。当您注销会话时,SQL-Server 表将被删除,并且需要为下一个会话重新创建。在 Oracle 中,临时表现在是模式的永久部分,即使数据不是(如果不是,您可以决定是否保留它)。Oracle 只支持全局临时表,使您不必在每个会话中创建表;它“存在”但它是空的,并且每个会话的内容都是唯一的(和私有的)。
请注意,全局临时表没有与之关联的统计信息,因此请查看是否应设置实例的动态采样级别以确保在解析时对未分析的表进行采样。否则,启发式可能会导致令人讨厌的执行计划。
只是为了添加关于本地和全局临时表的现有答案,从Oracle 18c
那里将有真正的“私人临时表”:
私有临时表是在事务或会话结束时自动删除的临时数据库对象。私有临时表存储在内存中,仅对创建它的会话可见。
私有临时表将临时表的范围限制在会话或事务中,从而为应用程序编码提供更大的灵活性,从而更容易代码维护和更好的即用型功能。
Oracle Live SQL演示:18c 私有临时表:
-- Private temporary tables must be prefixed as per the database parameter
-- 'private_temp_table_prefix'
create private temporary table ORA$PTT_MY_TT ( x int );
-- The table is truly private.
-- It does not even exist in the the data dictionary, only your session
-- By default, the moment you commit, the table ceases to exist
commit;
select * from ORA$PTT_MY_TT;
-- ORA-00942: table or view does not exist
-- This can be changed by specifying that the definition should be preserved
create private temporary table ORA$PTT_MY_TT ( x int )
on commit preserve definition;
insert into ORA$PTT_MY_TT
select rownum from dual
connect by level <= 30;
commit;
select count(*) from ORA$PTT_MY_TT;
-- 30
此外,当您的每个用户/会话都需要查看不同的数据集时,Oracle(全局)临时表非常有用。只需将记录插入到您的全局临时表中,让 Oracle 管理将一个用户的集合与另一个用户的集合以及清理工作保持一致。您不需要使用用户 ID、会话 ID 或其他任何内容来查询它们。
我们发现它们非常方便。
没有临时表,只有全局临时表。全局临时表的想法是定义存在并且所有人都可以看到,但数据对于每个会话都是私有的。您还可以配置是在提交时清理数据还是仅在会话结束时清理数据。