简体   繁体   English

全局临时表 (GTT) 和 collections 之间的区别

[英]Difference between Global temporary table (GTT) and collections

I wanted to know the difference between GTT and collections with scenarios where to use GTT and where to use collections.我想知道 GTT 和 collections 之间的区别,以及使用 GTT 和使用 collections 的场景。

Global Temporary Tables are permanent data structures.全局临时表是永久数据结构。 We can manipulate data in a GTT using SQL like any other table.我们可以像任何其他表一样使用 SQL 操作 GTT 中的数据。 What distinguishes them from regular heap tables is:它们与常规堆表的区别在于:

  1. Their data is transient, and only persists for the duration of a transaction or a session (depending on definition).它们的数据是瞬态的,仅在事务或 session(取决于定义)期间持续存在。
  2. They write their data to a temporary tablespace rather than a permanent tablespace.他们将数据写入临时表空间而不是永久表空间。

The second point is something people often overlook.第二点是人们经常忽略的一点。 Writing to and reading from global temporary tables entails disk i/o.写入和读取全局临时表需要磁盘 i/o。 So a GTT may not be the cheap cache we think it is.所以 GTT 可能不是我们认为的廉价缓存。 Also, it's worth making a separate temporary tablespace dedicated to GTTs, to avoid contention with other processes which use a temporary tablespace (such as disk sorts).此外,值得为 GTT 创建一个单独的临时表空间,以避免与使用临时表空间的其他进程(例如磁盘排序)争用。

PL/SQL collections are in-memory session variables. PL/SQL collections 是内存中的 session 变量。 Their storage allocation comes out of the Private SGA allocation - which can be quite small, depending on how the database is configured.它们的存储分配来自私有 SGA 分配 - 这可能非常小,具体取决于数据库的配置方式。 Although we query a collection using a SQL SELECT statement with a table() function, PL/SQL collections require the use of PL/SQL to define and populate them. Although we query a collection using a SQL SELECT statement with a table() function, PL/SQL collections require the use of PL/SQL to define and populate them.

So, when to use a GTT and when to use a collection?那么,什么时候使用 GTT,什么时候使用集合呢?

Use a GTT when we have a frequent need to use a result in multiple different queries.当我们经常需要在多个不同的查询中使用结果时,请使用 GTT。 This might manifest as a requirement to execute ad hoc queries over a temporary aggregation of data.这可能表现为对临时数据聚合执行即席查询的要求。 I stress the frequent need: these are permanent data structures, so we only build them when we have users (which includes things such as background report jobs) which are going to repeat the populate/query/discard routine with a defined projection of data.我强调经常需要:这些是永久的数据结构,所以我们只有在我们有用户(包括后台报告作业等)时才构建它们,这些用户将使用定义的数据投影重复填充/查询/丢弃例程。

Use a collection when we're writing procedural code which manipulates a small set of data (or a large set of data which can be broken up into smaller batches) where the subset is a by-product or stepping stone in the process, and not an artefact of interest in its own right.当我们编写程序代码来操作一小组数据(或一大组可以分解成较小批次的数据)时,请使用集合,其中子集是过程中的副产品或垫脚石,而不是本身就感兴趣的人工制品。 For instance, we might use collections to pass data sets between program units.例如,我们可以使用 collections 在程序单元之间传递数据集。

My personal experience is that collections are far more common than global temporary tables.我个人的经验是 collections 远比全局临时表常见。 The main definers of GTTs are probably developers with more experience of MSSQL than Oracle, who are writing translations of T-SQL rather than idiomatic Oracle code. GTT 的主要定义者可能是比 Oracle 更有 MSSQL 经验的开发人员,他们正在编写 T-SQL 的翻译而不是惯用的 Oracle 代码。 Sometime people think they need a GTT when what they actually need is a materialized view.有时人们认为他们需要 GTT,而实际上他们需要的是物化视图。

Finally, following on from that point, I would like to suggest that there is much less need to use GTTs or collections in Oracle than one might think.最后,从这一点开始,我想建议在 Oracle 中使用 GTT 或 collections 的需要比人们想象的要少得多。 SQL is very efficient at joining tables, and the overhead of populating and then reading GTTs is probably way higher than just executing a SQL statement. SQL 在连接表时非常有效,并且填充然后读取 GTT 的开销可能比仅执行 SQL 语句要高得多。 Certainly it's worth starting with just the SELECT statement, and only considering collections or GTTs if we can't tune the query down to an acceptable elapsed time.当然值得从 SELECT 语句开始,如果我们不能将查询调整到可接受的经过时间,则只考虑 collections 或 GTT。

Global temporary tables can have statistics as any other table.全局临时表可以像任何其他表一样具有统计信息。 In fact they are like any other table, they have data segments, just in temporary tablespace.事实上,它们和其他任何表一样,它们都有数据段,只是在临时表空间中。

The collection type cardinality is based on DB block size and for default 8 kB block is 8168. Collection content is stored in PGA.集合类型基数基于 DB 块大小,默认 8 kB 块为 8168。集合内容存储在 PGA 中。

Below would help you to understand better,下面将帮助您更好地理解,

Query cost: Global Temporary Tables vs. Collections (Virtual Arrays) 查询成本:全局临时表与 Collections(虚拟阵列)

The most important difference between collections and GTT in SQL, is that CBO(cost-based optimizer) has limitations for TABLE function (kokbf$...), for example JPPD doesn't work with TABLE() functions: https://jonathanlewis.wordpress.com/2020/01/13/collections/ The most important difference between collections and GTT in SQL, is that CBO(cost-based optimizer) has limitations for TABLE function (kokbf$...), for example JPPD doesn't work with TABLE() functions: https:// jonathanlewis.wordpress.com/2020/01/13/collections/

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM