【发布时间】:2020-10-30 21:46:24
【问题描述】:
我想知道 GTT 和集合之间的区别,以及在哪里使用 GTT 和在哪里使用集合的场景。
【问题讨论】:
我想知道 GTT 和集合之间的区别,以及在哪里使用 GTT 和在哪里使用集合的场景。
【问题讨论】:
全局临时表是永久性数据结构。我们可以像任何其他表一样使用 SQL 操作 GTT 中的数据。它们与常规堆表的区别在于:
第二点是人们经常忽略的。写入和读取全局临时表需要磁盘 i/o。所以 GTT 可能不是我们认为的廉价缓存。此外,值得为 GTT 创建一个单独的临时表空间,以避免与使用临时表空间的其他进程争用(例如磁盘排序)。
PL/SQL 集合是内存中的会话变量。它们的存储分配来自私有 SGA 分配 - 这可能非常小,具体取决于数据库的配置方式。虽然我们使用带有table() 函数的 SQL SELECT 语句查询集合,但 PL/SQL 集合需要使用 PL/SQL 来定义和填充它们。
那么,什么时候使用 GTT,什么时候使用集合?
当我们经常需要在多个不同的查询中使用结果时,请使用 GTT。这可能表现为对临时数据聚合执行即席查询的要求。我强调经常需要:这些是永久的数据结构,所以我们只有在我们有用户(包括后台报告作业等)时才构建它们,这些用户将使用定义的数据投影重复填充/查询/丢弃例程。
当我们编写程序代码来操作一小组数据(或可以分解成更小批次的大量数据)时,请使用集合,其中子集是过程中的副产品或垫脚石,而不是其本身的利益的人工制品。例如,我们可以使用集合在程序单元之间传递数据集。
我个人的经验是,集合比全局临时表要普遍得多。 GTT 的主要定义者可能是 MSSQL 比 Oracle 更有经验的开发人员,他们正在编写 T-SQL 的翻译而不是惯用的 Oracle 代码。有时人们认为他们需要 GTT,而实际上他们需要的是物化视图。
最后,从这一点开始,我想建议在 Oracle 中使用 GTT 或集合的需要比人们想象的要少得多。 SQL 在连接表方面非常有效,填充然后读取 GTT 的开销可能比仅执行 SQL 语句要高得多。当然,仅从 SELECT 语句开始是值得的,如果我们无法将查询调整到可接受的经过时间,则仅考虑集合或 GTT。
【讨论】:
全局临时表可以像任何其他表一样具有统计信息。事实上,它们和其他任何表一样,都有数据段,只是在临时表空间中。
集合类型基数基于 DB 块大小,默认 8 kB 块为 8168。集合内容存储在 PGA 中。
以下内容将帮助您更好地理解,
Query cost: Global Temporary Tables vs. Collections (Virtual Arrays)
【讨论】:
SQL 中集合和 GTT 最重要的区别是 CBO(基于成本的优化器)对 TABLE 函数(kokbf$...)有限制,例如 JPPD 不适用于 TABLE() 函数: https://jonathanlewis.wordpress.com/2020/01/13/collections/
【讨论】: