默认情况下,表被组织为堆(即堆组织表),这意味着数据库会将行放置在最适合它们的位置,而不是按照用户指定的顺序。
当用户添加行时,数据库会将这些行放置在数据段中的第一个可用空间中。不保证按插入顺序检索行。
8.2.1.1数据块和段中的行存储:入门
数据库将行存储在数据块中。在表中,数据库可以在块底部的任意位置写一行。Oracle数据库使用包含行目录和表目录的块开销来管理块本身。
范围由逻辑上连续的数据块组成。这些块在磁盘上可能不是物理连续的。段是一组扩展,其中包含表空间内逻辑存储结构的所有数据。例如,Oracle数据库分配一个或多个扩展区以形成表的数据段。数据库还分配一个或多个扩展区以形成表的索引段。
默认情况下,数据库对本地管理的永久表空间使用自动段空间管理(ASSM)。当会话首次将数据插入表中时,数据库将格式化位图块。位图跟踪段中的块。数据库使用位图查找可用块,然后在写入每个块之前对其进行格式化。ASSM在块之间分散插入,以避免并发问题。
高水位标记(HWM)是段中的点,超出该点(即高水位外的),数据块将被格式化并且从未使用过。在HWM下方,可以对一个块进行格式化和写入,对其进行格式化并使其为空或不进行格式化。低高水位标记(low HWM)标记了一个点,在该点以下,已知所有块都将被格式化,因为它们包含数据或以前包含数据。 (注意:HWM和低HWM之间 有可能存在未进行格式化的块,这些未格式化的块在全表扫描时,不被读取)
在全表扫描期间,数据库将读取所有已知要格式化的低HWM块,然后读取段位图以确定HWM和低HWM之间的哪些块已格式化且可以安全读取。数据库知道不要读取HWM,因为这些块是未格式化的。
也可以看看:
Oracle Database Concepts了解数据块存储
8.2.1.2行访问的行标识符的重要性
堆组织表中的每一行都具有该表唯一的rowid,该rowid对应于一个行的物理地址。rowid是一行的10字节物理地址。
rowid指向特定的文件,块和行号。例如,在rowid中AAAPecAAFAAAABSAAA,final AAA表示行号。行号是行目录项的索引。行目录条目包含一个指向该行在块上位置的指针。
数据库有时可以在块的底部移动一行。例如,如果启用了行移动,则行可以由于分区键更新,闪回表操作,收缩表操作等而移动。如果数据库在块内移动了一行,则数据库将更新行目录条目以修改指针。rowid保持不变(即行链接)。
行迁移: 行迁移是指一个数据行不适合放入当前块而被重新定位到另一个块,但在原始块中保留一个指针,原始块中的指针是必需的,因为索引的rowid项仍然指向原始位置. oracle 在决定行连接之前先试图进行行迁移。 当使用全表扫描时,转移地址被忽略。因为我们最终能够获得所有的数据,所以能够忽略其转移地址。因此行迁移并不会对全表扫描产生额外的操作。 行迁移对索引读产生额外的I/O : 这是由于索引告诉我们通过文件X,块Y,slot槽Z可以获得该行数据。 但是当我们根据地址信息达到所在位置时,从其转移地址得知,其真实的数据是存储在文件A,块B,slot槽C上。因此为了寻找该行数据不得不产生额外的逻辑或物理I/O。行链接: rowid 保持不变,是指一个行存储在多个块中的情况,因为一个该行的长度超过了一个块的可用空间大小, 如果读取整行,会比普通行多读一个块, 如果读部份例,只要所查询的例不在行移动后的块,则不影响性能。 如果所查询的例在行移动后的块中, 则对性能有所影响 table fetch continued rowOracle数据库内部使用rowid来构建索引。例如,B树索引中的每个键都与一个指向关联行地址的rowid关联。物理rowid提供对表行的尽可能最快的访问,使数据库能够以最少的I / O检索行。
8.2.1.3直接路径读取
在直接路径读取中,数据库从磁盘直接将缓冲区读取到PGA中,而完全绕开了SGA。
下图显示了分散读取和顺序读取(将缓冲区存储在SGA中)和直接路径读取之间的区别。
图8-1直接路径读取
Oracle数据库可能执行直接路径读取的情况包括:
- 执行
CREATE TABLE AS SELECT - 执行
ALTER REBUILD或ALTER MOVE - 从临时表空间读取
- 并行查询
- 从LOB段读取




