`
benx
  • 浏览: 276201 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

数据库表(临时表)

阅读更多
Oracle中的段(segment)是占用磁盘上存储空间的一个对象。尽管有多种类型,不过最常见的段类型如下:
q         聚簇(cluster):这种段类型能存储表。有两种类型的聚簇:B*树聚簇和散列聚簇。聚簇通常用于存储多个表上的相关数据,将其“预联结”存储到同一个数据库块上;还可以用于存储一个表的相关信息。“聚簇”这个词是指这个段能把相关的信息物理的聚在一起。
q         表(table):表段保存一个数据库表的数据,这可能是最常用的段类型,通常与索引段联合使用。
q         表 分区(table partition)或子分区(subpartition):这种段类型用于分区,与表段很相似。分区表由一个或多个分区段(table partition segment)组成,组合分区表则由一个或多
个表子分区段(table subpartition segment)组成。
q         索引(index):这种段类型可以保存索引结构。
q         索引分区(index partition):类似与表分区,这种段类型包含一个索引的某个片。分区索引由一个或多个索引分区段(index partition segment)组成。
q         Lob分 区(lob partition)、lob子分区(lob subpartition)、lob索引(lobindex)和lob段(lobsegment):lobindex和lobsegment段保存大对象(large object或LOB)的结构。对包含LOB的表分区时,lobsegment也会分区,lob分区段(lob partition segment)正是用于此。有意思的是,并没有一种lobindex分区段(lobindex partition segment)类型——不论出于什么原因,Oracle将分区lobindex标记为一个索引分区(有人很奇怪为什么要另外给lobindex取一个特 殊的名字!)。
q         嵌套表(nested table):这是为嵌套表指定的段类型,它是主/明细关系中一种特殊类型的“子”表,这种关系随后将详细讨论。
q         回滚段(rollback)和Type2 undo段:undo数据就存储在这里。回滚段是DBA手动创建的段。Type2 undo段由Oracle自动创建和管理。


段空间管理
从Oracle 9i开始,管理段空间有两种方法:
q         手 动段空间管理(Manual Segment Space Management):由你设置FREELISTS、FREELIST GROUPS、PCTUSED和其他参数来控制如何分配、使用和重用段中的空间。在这一章中我会把这种空间管理方法称为MSSM,但是要记住,这是一个我 自造的缩写,Oracle文档中没有这个缩写。
q         自动段空间管理(Automatic Segment Space Management, ASSM):你只需控制与空间使用相关的一个参数:PCTFREE。创建段时也可以接受其他参数,但是这些参数将被忽略。


高水位线
HWM很重要, 因为Oracle在全面扫描段时会扫描HWM之下的所有块, 即使其中不包含任何数据。这会影响全面扫描的性能,特别是当HWM之下的大多数块都为空时。要查看这种情况,只需创建一个有1,000,000行的表(或者创建其他有大量行的表),然后对这个表执行一个SELECT COUNT(*)。 下面再删除(DELETE)这个表中的每一行,你会发现尽管SELECT COUNT(*)统计出0行,但是它与统计出1,000,000所花的时间一样长(如果需要完成块清除,时间可能还会更长:有关内容请参加9.5.5 节)。这是因为Oracle在忙于读取HWM之下的所有块, 查看其中是否包含数据。 如果对这个表使用TRUNCATE而不是删除其中的每一行,你可以比较 一下结果有什么不同。TRUNCATE会把表的HWM重置回“0”,还会截除表上的相关索引。由于以上原因,如果你打算删除表中的所有行,就应该选择使用 TRUNCATE
(如果可以使用的话)



临时表(Temporary table)用于保存事务或会话期间的中间结果集。临时表中保存的数据只对当前会话可见,所有会话都看不到其他会话的数据;即使当前会话已经提交 (COMMIT)了数据,别的会话也看不到它的数据。对于临时表,不存在多用户并发问题,因为一个会话不会因为使用一个临时表而阻塞另一个会话。即使我们 “锁住”了临时表,也不会妨碍其他会话使用它们自己的临时表。
临时表比常规表生成的redo少得多。不过,由于临时表必须为其中包含 的数据生成undo信息, 所以也会生成一定的redo。 UPDATE和DELETE会生成最多的undo; INSERT和SELECT生成的undo最 少。


临 时表会从当前登录用户的临时表空间分配存储空间,或者如果从一个定义者权限(definer right)过程访问临时表,就会使用该过程所有者的临时表空间。全局临时表实际上是表本身的一个模板。创建临时表的动作不涉及存储空间分配;不会为此分 配初始(INITIAL)区段,这与常规表有所不同。对于临时表,运行时当一个会话第一次在临时表中放入数据时,才会为该会话创建一个临时段。由于每个会 话会得到其自己的临时段(而不是一个现有段的一个区段),每个用户可能在不同的表空间为其临时表分配空间。


Oracle的 临时表与其他关系数据库中的临时表类似,这样区别只是:Oracle的临时表是“静态”定义的。每个数据库只创建一次临时表,而不是为数据库中的每个存储过程都创建一次。在Oracle中,临时表一定存在,它们作为对象放在数据字典中,但是在会话向临时表中放入数据之前,临时表看上去总是空。由于临时表是静态定义的,所以你能创建引用临时表的视图,还可以创建存储过程使用静态SQL来引用临时表,等等。临时表可以是基于会话的(临时表中的数据可以跨提交存在,即提交之前仍然存在,但是断开连接后再连接后再连接时数据就没有了),也可以是基于事务的(提交之后数据就消失)。下面
这个例子显示了这两种不同的临时表
create global temporary table temp_table_session
2    on commit preserve rows
3    as
4    select * from scott.emp where 1=0
这是创建会话临时表

ON COMMIT DELETE ROWS子句使得这是一个基于事务的临时表

如果你曾在SQL Server和/或Sybase中用过临时表,现在所要考虑的主要问题是:不应该执行SELECT X, Y, Z INTO #TEMP FROM SOME_TABLE来动态创建和填充一个临时表,而应该:将所有全局临时表只创建一次,作为应用安装的一部分,就像是创建永久表一样。在你的过程中,只需执行INSERT INTO TEMP(X, Y, Z) SELECT X, Y, Z FROM SOME_TABLE。


归根结底,这里的目标是:不要在运行时在你的存储过程中创建表。这不是Oracle中使用临时表的正确做法。DDL是一种代价昂贵的操作:你要全力避免在运行时执行这种操作。一个应用的临时表应该在应用安装期间创建,绝对不要在运行时创建。

临时表可以有永久表的许多属性。它们可以有触发器、检查约束、索引等。但永久表的某些特性在临时表中并不支持,这包括:
q         不能有引用完整性约束。临时表不能作为外键的目标,也不能在临时表中定义外键。
q         不能有NESTED TABLE类型的列。 在Oracle 9i及以前版本中, VARRAY类型的列也不允许;
不过Oracle 10g中去掉了这个限制。
q         不能是IOT。
q         不能在任何类型的聚簇中。
q         不能分区。
q         不能通过ANALYZE表命令生成统计信息。
在 所有数据库中,临时表的缺点之一是优化器不能正常地得到临时表的真实统计。使用基于代价的优化器(cost-based optimizer,CBO)时,有效的统计对于优化器的成败至关重要。如果没有统计信息,优化器就只能对数据的分布、数据量以及索引的选择性作出猜测。 如果这些猜测是错的,为查询生成的查询计划(大量使用临时表)可能就不是最优的。在许多情况下,正确的解决方案是根本不使用临时表,而是使用一个 INLINE VIEW(要看INLINE VIEW的例子,可以查看前面运行的SELECT,它就有两个内联视图)。采用这种方式,Oracle可以访问一个表的所有相关统计信息,而且得出一个最 优计划

我经常发现,人们之所以使用临时表,是因为他们在其他数据库中了解到一个查询中联结太多的表是一件“不好的事情”。但在Oracle开发中,必须把这个知识忘掉。不要想着你比优化器要聪明,来一个查询分解成3个或4个查询,将其子结果存储在临时表中,然后再合并这些临时表;正确的做法是应该编写一个查 询,直接回答最初的问题。在一个查询中引用多个表是可以的;Oracle中在这个方面不需要临时表的帮助



临时表小结
如 果应用中需要临时存储一个行集由其他表处理(可能对应一个会话,也可能对应一个事务),临时表就很有用。不要把临时表作为一个分解大查询的方法,即拿到一 个大查询,把它“分解”为几个较小的结果集,然后再把这些结果集合并在一起(这看来是其他数据库中最常见的临时表用法)。实际上,你会发现,在几乎所有的 情况下。Oracle中如果将一个查询分解为较小的临时表查询,与原来的一个查询相比,只会执行得更慢。我就经常看到人们这样做,如果有可能把对临时表的 一系列INSERT重写为一个大查询(SELECT),所得到的单个查询会比原来的多步过程快得多。   

临 时表会生成少量的redo,但是确实还是会生成redo,而且没有办法避免。这些redo是为回滚数据生成的,而且在最典型的情况下,可以忽略不计。如果 只是对临时表执行INSERT和SELETE,生成的redo量几乎注意不到。只有对临时表执行大量DELETE和UPDATE时,才会看到生成大量的 redo。 如果精心设计,可以在临时表上生成CBO使用的统计信息;不过,可以使用DBMS_STATS包对临时表上的统计给出更好的猜测,或者由优化器使用动态采样在硬解析时动态收集。


分享到:
评论

相关推荐

    主流数据库中临时表的使用

    主流数据库中临时表的使用 在主流数据库中,临时表是一种特殊类型的表,它们是临时存储数据的容器。临时表可以在不同的数据库管理系统中使用,本文将对 MS SQLSERVER、Oracle 和 DB2 中的临时表进行介绍。 MS SQL ...

    简单理解数据库临时表

    ### 数据库临时表详解 #### 一、临时表的概念与作用 在数据库操作过程中,我们经常会遇到需要存储一些中间结果或临时数据的情况。这时候,**临时表**就发挥了其独特的作用。临时表,正如其名,是根据需求临时创建...

    NC6.5 数据库参考脚本及临时表空间配置.pdf

    根据提供的文件信息,本文将详细说明关于“NC6.5 数据库参考脚本及临时表空间配置”的知识点。 首先,文档标题“NC6.5 数据库参考脚本及临时表空间配置.pdf”指出了文件内容涉及三个方面:NC6.5数据库、参考脚本...

    Delphi演示数据库的临时表应用例子..rar

    在IT行业中,Delphi是一款强大的RAD(快速应用程序开发)...总之,掌握在Delphi中使用数据库临时表的技术对于提高应用程序的性能和效率至关重要。通过实践和学习提供的示例代码,开发者可以更好地理解和应用这一技巧。

    NC6.1 数据库参考脚本及临时表要求

    数据库临时表空间是数据库存储临时数据的区域,它对数据库性能有着重要的影响。在执行大规模数据处理任务时,合理配置临时表空间能有效提高数据库的处理能力。 对于SQL Server数据库,参考脚本的主要内容包括创建...

    HIS数据库表结构详细设计.doc

    24. **门诊收费医保处方临时表 (BM_SFCF00_TEMP00)** 和 **门诊收费医保处方明细临时表 (BM_SFCFMX_TEMP00)**:这两张临时表用于处理医保相关的门诊收费信息,可能用于计算医保报销比例和金额。 25. **(医疗)收费...

    不让临时表空间影响ORACLE数据库性能

    在Oracle数据库系统中,临时表空间是用于存储临时数据的特定区域,这些数据通常由排序、聚合、JOIN等操作产生。当处理大量数据或者运行复杂SQL查询时,临时表空间的作用尤为关键。然而,如果不正确地管理和使用临时...

    临时表操作详解SQL Server 实例

    在SQL Server中,临时表是一种特殊类型的数据库对象,它们用于存储临时数据,这些数据只在当前会话或特定范围内存在。临时表分为两种类型:本地临时表(Local Temporary Tables)和全局临时表(Global Temporary ...

    Oracle临时表空间满的解决步骤

    解决 Oracle 临时表空间满的问题需要通过查看当前数据库的默认临时表空间、查看当前临时表空间的大小、创建新的临时表空间、将新建的临时表空间设置为数据库的默认临时表空间、删除原来的临时表空间、创建新的临时表...

    django 删除数据库表后重新同步的方法

    在这种情况下,作者尝试了一个非常规的操作方法:使用python manage.py sqlmigrate命令查看框架自动生成的创建表SQL语句,然后直接在数据库中执行该SQL语句手动创建了表。这种方法虽然不是标准做法,但在无法通过...

    android 数据库表结构更新步骤

    - 若要删除字段,通常需要先创建一个新的临时表,将旧表数据迁移过来,然后删除旧表并重命名新表为旧表名。例如,删除`age`字段: ```java String CREATE_TEMP_TABLE = "CREATE TABLE temp_table AS SELECT id, ...

    不要让临时表空间影响数据库性能

    临时表空间在数据库操作中扮演着关键角色,尤其是在处理复杂查询和大型数据集时。虽然看似只是临时存储,但实际上它对数据库性能有着重大影响。如果临时表空间配置不当,可能会导致性能显著下降。因此,管理员需要...

    浅谈SQL数据库中滥用临时表、排序的解决方案

    在SQL数据库中,临时表和排序是两个常见的操作,但过度依赖它们可能会导致性能问题。本文将探讨如何避免滥用临时表和排序,并提供一个具体的案例来阐述解决方案。 首先,临时表在处理大量数据时可以提供便利,但...

    如何解决Oracle8i数据库临时表空间满的问题.pdf

    从标题和描述中,我们可以了解到该文档主要讲述了Oracle8i数据库临时表空间满时的解决方案。Oracle8i是甲骨文公司推出的一个关系型数据库管理系统,它是Oracle数据库的一个版本,在业界有着广泛的应用。临时表空间...

    SpringBoot 整合Mybatis 创建临时表

    这里我们使用Mybatis的注解来定义SQL语句,`@Insert`用于创建临时表,`@Select`用于查询临时表中的数据。注意,临时表在会话结束时会被自动删除,所以它们只对当前连接可见。 接着,我们需要创建一个对应的实体类`...

    sqlserver中判断表或临时表是否存在

    SQL Server 中判断表或临时表是否存在 在 SQL Server 中判断表或临时表是否存在是非常重要的操作,以下将详细介绍如何判断表或临时表是否存在。 判断数据表是否存在 判断数据表是否存在可以使用两种方法。 方法...

    数据库表设计原则技巧

    理解这些特性有助于我们在设计数据库时区分基本表与中间表、临时表,从而构建更加合理高效的数据结构。 #### 四、范式标准 基本表及其字段之间的关系应尽量满足第三范式。然而,满足第三范式的数据库设计虽然减少...

    计算机等考三级数据库基础:临时表和游标的使用小总结.docx

    在计算机等考三级数据库基础的学习中,临时表和游标是两个重要的概念,尤其是在处理数据操作和查询时。本文将对这两个概念进行深入的总结。 首先,临时表是一种特殊的数据库对象,它存在于`tempdb`系统数据库中。...

    SQL Server中关于临时表概念及创建和插入数据等问题

    在 Oracle 数据库中,也有临时表的概念。临时表可以分为事务临时表和会话临时表。事务临时表是指数据只有在当前事务内有效,关闭事务后,数据表中的内容将被删除。会话临时表是指数据只在当前会话内有效,关闭当前...

    关系数据库表存储树形结构的方法

    检索子节点时,可以通过临时表来模拟队列操作,逐层向下检索。检索父节点则直接通过指针字段进行。 插入新节点时,只需知道其父节点的编号,并将其作为新节点的指针字段值。这样,新节点就被添加到了表中。 删除...

Global site tag (gtag.js) - Google Analytics