0
点赞
收藏
分享

微信扫一扫

Oracle Cluster Table(原创)


表集群概述

表集群是一组共享公共列并将相关数据存储在同一块中的表。对表进行集群时,单个数据块可以包含多个表中的行。例如,块可以同时存储 和 表中的行,而不是仅存储单个表中的行。​employees​​departments​

群集键 例如,和 表共享列。您可以在创建表集群和创建添加到表集群的每个表时指定集群键。​employees​​departments​​department_id​

群集键值是一组特定行的群集键列的值。包含相同群集密钥值的所有数据(如 )都以物理方式存储在一起。每个集群键值在集群和集群索引中仅存储一次,无论不同表包含多少行。​department_id=20​

打个比方,假设人力资源经理有两个书柜:一个是员工文件夹盒,另一个是部门文件夹框。用户经常要求特定部门中所有员工的文件夹。为了使检索更容易,经理重新排列了单个书柜中的所有盒子。她按部门 ID 划分框。因此,部门 20 中员工的所有文件夹和部门 20 本身的文件夹都在一个框中;部门 100 中员工的文件夹和部门 100 的文件夹位于不同的框中,依此类推。

当主要查询(但未修改)表并且表中的记录经常一起查询或联接时,可以考虑对表进行聚类分析。

  • 对于群集表的联接,磁盘 I/O 减少。
  • 集群表联接的访问时间得到改善。
  • 存储相关表和索引数据所需的存储空间更少,因为不会为每行重复存储集群键值。

通常,群集表不适用于以下情况:

  • 这些表经常更新。
  • 这些表经常需要全表扫描。
  • 这些表需要截断。

索引群集概述



索引集群是使用索引查找数据的表集群。群集索引是群集键上的 B 树索引。必须先创建集群索引,然后才能将任何行插入到集群表中。

假设您使用集群密钥创建集群,如示例 2-8 所示。由于未指定子句,因此此群集是已编制索引的群集。然后,创建一个以此群集密钥命名的索引。​employees_departments_cluster​​department_id​​HASHKEYS​​idx_emp_dept_cluster​



示例 2-8 索引群集



创建群集employees_departments_cluster (department_id 编号(4)) 大小 512;在集群employees_departments_cluster上创建索引idx_emp_dept_cluster;



然后,在群集中创建 和 表,将列指定为群集键,如下所示(省略号标记列规范的位置):​employees​​departments​​department_id​



创建表员工 ( ... )第employees_departments_cluster组(department_id);创建表部门 ( ... )第employees_departments_cluster组(department_id);



最后,向 和 表中添加行。数据库以物理方式将每个部门的所有行从 和 表存储在相同的数据块中。数据库将这些行存储在堆中,并使用索引找到它们。​employees​​departments​​employees​​departments​

图 2-6 显示了表群集,其中包含 和 。数据库将部门 20 中员工的行存储在一起,将部门 110 中的员工存储到一起,依此类推。如果表未进行聚类,则数据库不会确保相关行存储在一起。​employees_departments_cluster​​employees​​departments​



图2-6 聚类表数据



Oracle Cluster Table(原创)_oracle


“图 2-6 群集表数据”的说明



B 树群集索引将群集键值与包含数据的块的数据库块地址 (DBA) 相关联。例如,键 20 的索引条目显示包含部门 20 中员工数据的块的地址:



20,阿达亚9d



集群索引是单独管理的,就像非聚集表上的索引一样,并且可以存在于与表集群不同的表空间中。

哈希集群概述



哈希群集类似于已编制索引的群集,只是索引键被替换为哈希函数。不存在单独的群集索引。在哈希群集中,数据是索引。

对于索引表或索引群集,Oracle 数据库使用存储在单独索引中的键值来查找表行。要在索引表或表集群中查找或存储行,数据库必须至少执行两个 I/O:

  • 一个或多个 I/O,用于在索引中查找或存储密钥值
  • 另一个 I/O,用于读取或写入表或表集群中的行

若要在哈希群集中查找或存储行,Oracle 数据库会将哈希函数应用于该行的群集键值。生成的哈希值对应于集群中的数据块,数据库代表发出的语句读取或写入该数据块。

哈希是存储表数据的可选方法,可提高数据检索的性能。当满足以下条件时,哈希群集可能很有用:

  • 查询表的频率远远高于修改频率。
  • 例如,经常使用相等条件查询哈希键列。对于此类查询,将对群集键值进行哈希处理。哈希键值直接指向存储行的磁盘区域。​WHERE department_id=20​
  • 您可以合理地猜测哈希键的数量以及与每个键值一起存储的数据的大小。

哈希集群创建

与索引集群的密钥一样,集群键是由集群中的表共享的单列或复合密钥。哈希键值是插入到群集键列中的实际值或可能值。例如,如果群集密钥为 ,则哈希密钥值可以是 10、20、30 等。​department_id​

Oracle 数据库使用哈希函数,该函数接受无限数量的哈希键值作为输入,并将它们分类到有限数量的存储桶中。每个存储桶都有一个唯一的数字 ID,称为哈希值。每个哈希值都映射到存储与哈希键值(部门 10、20、30 等)对应的行的块的数据库块地址。

要创建哈希集群,请使用与索引集群相同的语句,并添加哈希键。群集的哈希值数取决于哈希键。在示例 2-9 中,可能存在的部门数为 100,因此设置为 。​CREATE CLUSTER​​HASHKEYS​​100​



示例 2-9 哈希群集



创建群集employees_departments_cluster (department_id编号(4)) 大小 8192 哈希键 100;



创建 后,可以在群集中创建 和 表。然后,您可以将数据加载到哈希集群中,就像在示例 2-8 中描述的索引集群中一样。​employees_departments_cluster​​employees​​departments​



哈希群集查询

数据库(而不是用户)确定如何对用户输入的键值进行哈希处理。例如,假定用户经常执行如下查询,为 输入不同的部门 ID 号:​p_id​



从员工中选择 * department_id = :p_id;从department_id = :p_id 的部门中选择 * ;从员工 e、部门 d 中选择 * 其中 e.department_id = d.department_id 并且 d.department_id = :p_id;



如果用户在 中查询员工,则数据库可能会将此值哈希为存储桶 77。如果用户在 = 中查询员工,则数据库可能会将此值哈希为存储桶 15。数据库使用内部生成的哈希值来查找包含所请求部门的员工行的块。​department_id​​=20​​department_id​​10​

图 2-7 将哈希簇段描述为水平块行。如图所示,查询可以在单个 I/O 中检索数据。



图 2-7 从哈希群集中检索数据



Oracle Cluster Table(原创)_oracle_02


“图 2-7 从哈希群集检索数据”的说明


哈希群集的一个限制是无法对未编制索引的群集键进行范围扫描(请参阅“索引范围扫描”)。假定在示例 2-9 中创建的哈希集群不存在单独的索引。对 ID 介于 20 和 100 之间的部门的查询不能使用哈希算法,因为它无法对 20 到 100 之间的每个可能值进行哈希处理。由于不存在索引,因此数据库必须执行完全扫描。



哈希群集变体


单表哈希群集是哈希群集的优化版本,一次仅支持一个表。哈希键和行之间存在一对一映射。当用户需要通过主键快速访问表时,单表哈希群集可能很有用。例如,用户经常通过以下方式在表中查找员工记录:​employees​

​​.​employee_id​


已排序的哈希群集 数据库在内部执行优化的排序。对于始终按排序顺序使用数据的应用程序,此技术可能意味着更快地检索数据。例如,应用程序可能始终按表的列进行排序。​order_date​​orders​



哈希群集存储

Oracle 数据库为哈希群集分配空间的方式与索引群集不同。在示例 2-9 中,指定可能存在的部门数,而指定与每个部门关联的数据的大小。数据库根据以下公式计算存储空间值:​HASHKEYS​​SIZE​



哈希键 * 大小 / database_block_size



Thus, if the block size is 4096 bytes in ​​Example 2-9​​, then the database allocates at least 200 blocks to the hash cluster.

Oracle Database does not limit the number of hash key values that you can insert into the cluster. For example, even though ​​​ is ​​​, nothing prevents you from inserting 200 unique departments in the ​​ table. However, the efficiency of the hash cluster retrieval(231, 243, 237); padding: 0px 3px; border-radius: 4px; overflow-wrap: break-word; text-indent: 0px;">​HASHKEYS​​100​​departments​

To illustrate the retrieval(231, 243, 237); padding: 0px 3px; border-radius: 4px; overflow-wrap: break-word; text-indent: 0px;">​department_id​​departments​​HASHKEYS​​department_id​​department_id​

When users insert rows into the cluster for department 43, the database cannot store these rows in block 100, which is full. The database links block 100 to a new overflow block, say block 200, and stores the inserted rows in the new block. Both block 100 and 200 are now eligible to store data for either department. As shown in ​​Figure 2-8​​​, a query of either department 20 or 43 now requires two I/Os to retrieve the data: block 100 and its associated block 200. You can solve this problem by re-creating the cluster with a different ​​ value.​HASHKEYS​

Figure 2-8 Retrieving Data from a Hash Cluster When a Hash Collision Occurs

Oracle Cluster Table(原创)_oracle_03


“图 2-8 发生哈希冲突时从哈希群集检索数据”的说明

指定平均群集键及其关联行所需的空间

该语句有一个可选子句 ,它是平均聚类键及其关联行所需的估计字节数。数据库在执行以下任务时使用该参数:​CREATE CLUSTER​​SIZE​​SIZE​

  • 估计可以容纳在集群数据块中的集群键(和关联行)的数量
  • 限制放置在群集数据块中的群集键数。这可以最大限度地提高群集中密钥的存储效率。

不限制给定群集键可以使用的空间。例如,如果设置为两个群集键可以放在一个数据块中,则任一群集键仍可以使用任意数量的可用数据块空间。​SIZE​​SIZE​

默认情况下,数据库在集群数据段的每个数据块中仅存储一个集群键及其关联的行。尽管块大小可能因操作系统而异,但当集群表导入到其他系统上的其他数据库时,将保留每个块的一个键的规则。

如果给定集群键值的所有行都无法放在一个块中,则这些块将链接在一起以加快对具有给定键的所有值的访问。集群索引指向块链的起点,每个块都包含集群键值和关联的行。如果集群使得多个密钥适合一个块,则块可以属于多个链。​SIZE​


指定平均群集键及其关联行所需的空间

该语句有一个可选子句 ,它是平均聚类键及其关联行所需的估计字节数。数据库在执行以下任务时使用该参数:​CREATE CLUSTER​​SIZE​​SIZE​

  • 估计可以容纳在集群数据块中的集群键(和关联行)的数量
  • 限制放置在群集数据块中的群集键数。这可以最大限度地提高群集中密钥的存储效率。

不限制给定群集键可以使用的空间。例如,如果设置为两个群集键可以放在一个数据块中,则任一群集键仍可以使用任意数量的可用数据块空间。​SIZE​​SIZE​

默认情况下,数据库在集群数据段的每个数据块中仅存储一个集群键及其关联的行。

如果给定集群键值的所有行都无法放在一个块中,则这些块将链接在一起以加快对具有给定键的所有值的访问。集群索引指向块链的起点,每个块都包含集群键值和关联的行。如果集群使得多个密钥适合一个块,则块可以属于多个链。​SIZE​


估计簇大小并设置存储参数

以下是在创建集群之前估算集群大小的好处:

  • 您可以使用集群的组合估计大小以及索引和重做日志文件的估计值来确定保存预期数据库所需的磁盘空间量。根据这些估计,您可以做出正确的硬件购买和其他决策。
  • 您可以使用单个群集的估计大小来更好地管理群集将使用的磁盘空间。创建集群后,您可以设置适当的存储参数,提高使用集群的应用程序的 I/O 性能。

使用 or 语句的子句(而不是将表放入群集的单个 或 语句)来设置群集的数据段的存储参数。创建或更改集群表时指定的存储参数将被忽略。为集群设置的存储参数将覆盖表存储参数。​STORAGE​​CREATE​​CLUSTER​​ALTER​​CLUSTER​​CREATE​​ALTER​

更改集群表


您可以使用该语句更改集群表。但是,您在集群表的语句中设置的任何数据块空间参数、事务条目参数或存储参数都会生成错误消息 ( )。数据库对所有集群表使用集群的参数。因此,您只能将该语句用于添加或修改列、删除非集群键列,或者添加、删除、启用或禁用集群表的完整性约束或触发器。​ALTER TABLE​​ALTER TABLE​​ORA-01771, illegal option for a clustered table​​ALTER TABLE​

创建哈希集群

使用语句创建哈希群集,但指定子句。以下语句创建一个名为 的群集,该群集由列(群集键)组成:​CREATE CLUSTER​​HASHKEYS​​trial_cluster​​trialno​


创建集群 trial_cluster ( trialno NUMBER(5,0) ) 表空间用户存储 ( 初始 250K 下一个 50K MINEXTENTS 1 最大扩展 3 PC界面 0 ) 哈希 IS trialno HASHKEYS 150;


以下语句在哈希群集中创建表:​trial​​trial_cluster​


创建表试用 ( trialno Number(5,0) 主键, ... )第trial_cluster组(审判号);


与索引簇一样,哈希簇的键可以是单列或复合键(多列键)。在前面的示例中,键是列。​trialno​

在本例中,该值指定并限制哈希函数可以生成的唯一哈希值的数量。数据库将指定的数字舍入为最接近的质数。​HASHKEYS​​150​

如果不是,您还可以使用 该子句指定用户定义的哈希函数。​HASH IS​​HASH IS​

您无法在哈希集群上创建集群索引,也无需在哈希集群键上创建索引。

控制哈希群集中的空间使用情况

创建哈希群集时,请务必正确选择群集键并设置 、 和 参数,以便最佳性能和空间使用。以下准则介绍如何设置这些参数。​HASH IS​​SIZE​​HASHKEYS​


选择密钥

选择正确的群集键取决于针对群集表发出的最常见查询类型。例如,考虑哈希群集中的表。如果查询经常按员工编号选择行,则该列应为群集键。如果查询经常按部门编号选择行,则该列应为群集键。对于包含单个表的哈希群集,群集键通常是所包含表的整个主键。​emp​​empno​​deptno​

哈希群集的键(如索引群集的键)可以是单列键,也可以是复合键(多列键)。具有复合键的哈希群集必须使用数据库的内部哈希函数。


设置哈希值 IS

仅当群集键是数据类型的单个列并且包含均匀分布的整数时,才指定参数。如果这些条件适用,则可以在集群中分布行,以便每个唯一的集群键值哈希值(两个集群键值具有相同的哈希值)为唯一的哈希值,而不会发生冲突。如果这些条件不适用,请省略此子句,以便使用内部哈希函数。​HASH IS​​NUMBER​



设置大小

应设置为保存任何给定哈希键的所有行所需的平均空间量。因此,要正确确定 ,您必须了解数据的特征:​SIZE​​SIZE​

  • 如果哈希群集仅包含单个表,并且该表中行的哈希键值是唯一的(每个值对应一行),则可以设置为群集中的平均行大小。​SIZE​
  • 如果哈希群集要包含多个表,则可以设置为保存与代表性哈希值关联的所有行所需的平均空间量。​SIZE​

此外,一旦确定了 的(初步)值,请考虑以下事项。如果值很小(可以为每个数据块分配四个以上的哈希键),则可以在语句中使用此值。但是,如果 的值很大(可以为每个数据块分配四个或更少的哈希键),则还应考虑预期的冲突频率以及数据检索的性能或空间使用效率对您来说是否更重要。​SIZE​​SIZE​​SIZE​​CREATE CLUSTER​​SIZE​

  • 如果哈希群集不使用内部哈希函数(如果已指定),并且您预计很少发生冲突或没有冲突,则可以使用初步值 。不会发生碰撞,空间得到尽可能有效的利用。​HASH IS​​SIZE​
  • 如果预计插入时会频繁发生冲突,则分配溢出块来存储行的可能性很高。为了减少溢出块的可能性,并在频繁发生冲突时最大限度地提高性能,应按下图所示进行调整。​SIZE​

Available Space for each Block / Calculated SIZE

Setting for SIZE

1

​SIZE​

2

​SIZE​​ + 15%

3

​SIZE​​ + 12%

4

​SIZE​​ + 8%

>4

​SIZE​

高估 的值会增加群集中未使用的空间量。如果空间效率比数据检索的性能更重要,请忽略上表中所示的调整,并使用 的原始值。​SIZE​​SIZE​


设置哈希键

为了在哈希群集中实现行的最大分布,数据库会将值向上舍入到最接近的质数。​HASHKEYS​


使用表集群提高性能

在决定是否对表进行集群时,请遵循以下准则:

  • 应用程序在连接语句中经常访问的集群表。
  • 如果应用程序仅偶尔联接表或经常修改表的公共列值,则不要对表进行聚类分析。修改行的群集键值比修改非聚集表中的值花费的时间更长,因为 Oracle 数据库可能需要将修改后的行迁移到另一个块来维护群集。
  • 如果应用程序经常仅对其中一个表执行全表扫描,则不要对表进行群集。群集表的全表扫描可能比非群集表的全表扫描花费更长的时间。Oracle 数据库可能会读取更多的块,因为这些表存储在一起。
  • 群集主从表(如果经常选择主记录,然后选择相应的详细信息记录)。详细记录存储在与主记录相同的数据块中,因此当您选择它们时,它们可能仍保留在内存中,因此需要 Oracle 数据库执行较少的 I/O。
  • 如果您经常选择同一主节点的多个详细信息记录,则将详细信息表单独存储在集群中。此度量值可提高选择同一主表的详细记录的查询的性能,但不会降低对主表进行全表扫描的性能。另一种方法是使用索引组织的表。
  • 如果具有相同集群键值的所有表中的数据超过一个或两个以上的数据块,则不要对表进行聚类。为了访问集群表中的行,Oracle 数据库会读取包含具有该值的行的所有块。如果这些行占用多个块,则访问单个行可能比访问非聚集表中的同一行需要更多的读取。
  • 当每个分类键值的行数变化很大时,不要对表进行聚类。这会导致低基数键值的空间浪费;它会导致高基数键值发生冲突。冲突会降低性能。

考虑群集对应用程序的好处和缺点。例如,您可能认为联接语句的性能提升大于修改集群键值的语句的性能损失。您可能希望试验处理时间,并将处理时间与单独群集和存储的表进行比较。


使用哈希群集提高性能

请遵循以下准则来选择何时使用哈希群集:

  • 使用哈希簇来存储由包含子句的 SQL 语句经常访问的表(如果子句包含使用相同列或列组合的相等条件)。将此列或列组合指定为群集键。​WHERE​​WHERE​
  • 如果可以确定保存具有给定集群键值的所有行(包括要立即插入的行和将来要插入的行)需要多少空间,则将表存储在哈希群集中。
  • 使用排序哈希群集,其中对应于哈希函数的每个值的行按升序对特定列进行排序,此时数据库可以缩短对此排序的群集数据的操作的响应时间。
  • 如果应用程序经常执行全表扫描,并且您必须为哈希群集分配大量空间以预期表增长,则不要将表存储在哈希群集中。此类全表扫描必须读取分配给哈希群集的所有块,即使某些块可能包含很少的行。单独存储表可减少全表扫描读取的块数。
  • 如果应用程序频繁修改集群键值,则不要将表存储在哈希集群中。修改行的群集键值可能比修改非群集表中的值花费更长的时间,因为 Oracle 数据库可能需要将修改后的行迁移到另一个块来维护群集。

无论该表是否经常与其他表联接,只要根据此列表中的注意事项,哈希值适合于该表,在哈希群集中存储单个表都很有用。

例子

创建集群:示例 以下语句创建一个以集群密钥列命名的集群,集群大小为 512 字节,存储参数值:​personnel​​department​


创建群集人员(部门编号(4))大小 512 存储(初始 100K 下一个 50K);


群集键:示例 以下语句在 的群集键上创建群集索引:​personnel​


创建集群人员索引idx_personnel;


创建集群索引后,可以将表添加到索引中,并对这些表执行 DML 操作。

将表添加到集群:示例 以下语句从示例表创建一些部门表,并将其添加到前面示例中创建的人员集群中:​hr.employees​


创建dept_10群集人员(department_id)的表,因为选择 *从员工department_id = 10;创建dept_20群集人员(department_id)的表,作为选择 *从员工中department_id = 20;


哈希集群:示例 以下语句创建一个以集群键列命名的哈希集群,最多 10 个哈希密钥值,每个值分配 512 个字节和存储参数值:​language​​cust_language​


创建集群语言 (cust_language VARCHAR2(3)) 大小 512 哈希键 10 存储 (初始 100k 下一个 50k);


由于前面的语句省略了该子句,因此 Oracle 数据库对群集使用内部哈希函数。​HASH​​IS​

以下语句创建一个以由列 和 组成的群集键命名的哈希群集,并将包含这些列的 SQL 表达式用于哈希函数:​address​​postal_code​​country_id​


创建集群地址 (postal_code号, country_id 字符 (2)) 哈希键 20 哈希 IS MOD(postal_code + country_id, 101);


单表哈希集群:示例 以下语句创建一个以集群键命名的单表哈希集群,最多 100 个哈希密钥值,每个值分配 512 个字节:​cust_orders​​customer_id​


创建集群 cust_orders (customer_id编号(6)) 大小 512 单表哈希键 100;


若要删除不包含表的集群及其集群索引,请使用 该语句。例如,以下语句删除名为 的空集群:​DROP CLUSTER​​emp_dept​


丢弃群集emp_dept;


如果集群包含一个或多个集群表,并且您也打算删除这些表,请添加语句的子句,如下所示:​INCLUDING TABLES​​DROP CLUSTER​


删除群集emp_dept包括表;


如果未包含该子句,并且集群包含表,则返回错误。​INCLUDING TABLES​

如果集群中的一个或多个表包含由集群外表的约束所引用的主键或唯一键,则除非同时删除从属约束,否则无法删除集群。这可以使用语句的子句轻松完成,如以下示例所示:​FOREIGN KEY​​FOREIGN KEY​​CASCADE CONSTRAINTS​​DROP CLUSTER​


删除集群emp_dept包括表级联约束;


如果不使用子句并且存在约束,则数据库将返回错误。​CASCADE CONSTRAINTS​

集群数据字典视图



以下视图显示有关哈希群集的信息:

视图

描述

​​​DBA_CLUSTERS​

​​​ALL_CLUSTERS​

​​S​USER_CLUSTER​

视图描述数据库中的所有集群(包括哈希集群)。视图描述了用户可访问的所有群集。视图仅限于用户拥有的集群。这些视图中的某些列包含由包或语句生成的统计信息。​DBA​​ALL​​USER​​DBMS_STATS​​ANALYZE​

​​​DBA_CLU_COLUMNS​

​​​USER_CLU_COLUMNS​

这些视图将表列映射到聚类列。

​​​DBA_CLUSTER_HASH_EXPRESSIONS​

​​​ALL_CLUSTER_HASH_EXPRESSIONS​

​​​USER_CLUSTER_HASH_EXPRESSIONS​

这些视图列出了哈希群集的哈希函数。

 

参考至:http://docs.oracle.com/cd/E11882_01/server.112/e25494/hash.htm#ADMIN11773

http://docs.oracle.com/cd/E11882_01/server.112/e25494/clustrs.htm#ADMIN11755

http://docs.oracle.com/cd/E11882_01/server.112/e40540/tablecls.htm#CNCPT89179

http://docs.oracle.com/cd/E11882_01/server.112/e41084/statements_5001.htm#SQLRF53808

本文原创,转载请注明出处、作者

如有错误,欢迎指正


举报

相关推荐

0 条评论