【问题标题】:Difference between Global temporary table (GTT) and collections全局临时表 (GTT) 和集合之间的区别
【发布时间】:2020-10-30 21:46:24
【问题描述】:

我想知道 GTT 和集合之间的区别,以及在哪里使用 GTT 和在哪里使用集合的场景。

【问题讨论】:

    标签: sql oracle plsql


    【解决方案1】:

    全局临时表是永久性数据结构。我们可以像任何其他表一样使用 SQL 操作 GTT 中的数据。它们与常规堆表的区别在于:

    1. 它们的数据是瞬态的,仅在事务或会话期间持续存在(取决于定义)。
    2. 他们将数据写入临时表空间而不是永久表空间。

    第二点是人们经常忽略的。写入和读取全局临时表需要磁盘 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。

    【讨论】:

      【解决方案2】:

      全局临时表可以像任何其他表一样具有统计信息。事实上,它们和其他任何表一样,都有数据段,只是在临时表空间中。

      集合类型基数基于 DB 块大小,默认 8 kB 块为 8168。集合内容存储在 PGA 中。

      以下内容将帮助您更好地理解,

      Query cost: Global Temporary Tables vs. Collections (Virtual Arrays)

      【讨论】:

      • 你能帮我举一个我们可以使用集合和 GTT 的场景示例吗?我的意思是说它们什么时候有用。
      【解决方案3】:

      SQL 中集合和 GTT 最重要的区别是 CBO(基于成本的优化器)对 TABLE 函数(kokbf$...)有限制,例如 JPPD 不适用于 TABLE() 函数: https://jonathanlewis.wordpress.com/2020/01/13/collections/

      一些解决方法:http://orasql.org/2019/05/30/workarounds-for-jppd-with-view-and-tablekokbf-xmltable-or-json_table-functions/

      【讨论】:

      • 你能帮我举一个我们可以使用集合和 GTT 的场景示例吗?我的意思是说它们什么时候有用。
      猜你喜欢
      • 1970-01-01
      • 2010-10-31
      • 2020-07-23
      • 2010-09-29
      • 1970-01-01
      • 2021-03-29
      • 2017-05-28
      • 1970-01-01
      • 2012-10-06
      相关资源
      最近更新 更多