Oracle中的cluster是什么意思,它有什么作用?

Oracle中的cluster是什么意思,它有什么作用?,第1张

大家对通常oracle中的cluster的理解是不准确的,经常和sql server中的cluster index混淆。Cluster是存储一组table的一种方法,这些table共享同一数据块中的某些相同column,并把不同table在这一共享column上值相同的data row存储到同一block上。在sql server中的cluster index强制行根据index key按存储顺序存储,这一点和oracle中的IOT类似。

从下图中我们可以清楚的看到cluster 和非cluster 的一组table的物理存储的区别。在cluster中,单个block上的数据可能来自多个table,概念上可以存储“预连接”的数据。单个table也可以使用cluster,即根据某些column按组存储数据。如图中,所有部门ID为 20和 110的部门信息和员工信息的数据都将存储在同一block。注意,这里存储的并不是排序的数据(那是IOT的任务),存储的是按部门ID分组集合的数据,是以heap的方式存储的。因此,部门20刚好和部门110相邻,而部门99和部门100相距很远(硬盘的物理位置)。

当单个block放不下时,额外的block将链接到最初的block,来包容溢出的数据,这种方式和在IOT中溢出block非常相似。

现在我们看看如何创建一个cluster。在cluster中创建一系列table是很简单的,对象存储定义如PCTFREE,PCTUSED,INITIAL都是和cluster相关的,而不是和table相关。这是因为在cluster中存储了若干table,每个table在同一个block中拥有不同的PCTFREE没有意义。

SQL>create cluster e_d_cluster

2 (deptid number(2))

3 size 1024

4 /

Cluster created

这里首先创建了一个index cluster。这个cluster的key为 deptid,在table中这个列可以不命名为deptid,但数据类型number(2)必须匹配。Size选项是用来告诉oracle预计有1024

字节数据和每个cluser key相关。Oracle将使用这个信息来计算每个block能容纳的最大cluster key数目。因此size太高,在每一block将得到很少的key,并且将使用比需要的更多的空间;设置容量太低,将得到过多的数据连接,这将偏离使用cluster的目的。Size是cluster的重要参数。

现在我们来创建cluster index。在把数据放入之前,需要索引cluster。Cluster index的作用是存储一个cluster key,并且返回包含该key的block的地址。

SQL>create index e_d_cluster_idx

2 on cluster e_d_cluster

3 /

Index created

Cluster key 的index可以使用index所有的正常的存储参数,并且可以位于另一个tablespace。它是一个正常的index,能够索引到一个cluster,并且也包含一个完全null的条目。

我们在cluster中创建table:

SQL>create table department

2 (deptid number(2) primary key,

3 dname varchar2(14),

4 loc varchar2(13))

5 cluster e_d_cluster(deptid)

Table created

SQL>create table employee

2 (empid number primary key,

3 ename varchar2(10),

4 job varchar2(10),

5 mgr number,

6 hiredate date,

7 sal number,

8 comm number,

9 deptid number(2) references department(deptid))

10 cluster e_d_cluster(deptid)

Table created

这里创建table与普通的table唯一的区别就是使用了cluster关键字,我们往table中装载数据:

SQL>begin

2 for x in(select * from scott.dept)

3 loop

4 insert into department

5 values(x.deptno,x.dname,x.loc)

6 insert into employee

7 select * from scott.emp

8 where deptno = x.deptno

9 end loop

10 end

11 /

PL/SQL procedure successfully completed

我们可以看到目前table中装载了如下数据:

SQL>select * from department

DEPTID DNAME LOC

------ -------------- -------------

10 ACCOUNTING NEW YORK

20 RESEARCH DALLAS

30 SALES CHICAGO

40 OPERATIONS BOSTON

SQL>select * from employee

EMPID ENAME JOB MGR HIREDATE SAL COMM DEPTID

---------- ---------- ---------- ---------- ----------- ---------- ---------- ------

7782 CLARK MANAGER 7839 1981-6-9 2450 10

7839 KING PRESIDENT 1981-11-17 5000 10

7934 MILLER CLERK 7782 1982-1-23 1300 10

7369 SMITH CLERK 7902 1980-12-17 800 20

7566 JONES MANAGER 7839 1981-4-2 2975 20

7788 SCOTT ANALYST 7566 1982-12-9 3000 20

7876 ADAMS CLERK 7788 1983-1-12 1100 20

7902 FORD ANALYST 7566 1981-12-3 3000 20

7499 ALLEN SALESMAN 7698 1981-2-20 1600 300 30

7521 WARD SALESMAN 7698 1981-2-22 1250 500 30

7654 MARTIN SALESMAN 7698 1981-9-28 1250 1400 30

7698 BLAKE MANAGER 7839 1981-5-1 2850 30

7844 TURNER SALESMAN 7698 1981-9-8 1500 0 30

7900 JAMES CLERK 7698 1981-12-3 950 30

现在我们看看这两个table数据存储的位置:

SQL>select dbms_rowid.rowid_block_number(department.rowid) dept_rid,

2 dbms_rowid.rowid_block_number(employee.rowid) emp_rid,department.deptid

3 from department,employee

4 where employee.deptid = department.deptid

DEPT_RID EMP_RID DEPTID

---------- ---------- ------

5587 5587 10

5587 5587 10

5587 5587 10

5587 5587 20

5587 5587 20

5587 5587 20

5587 5587 20

5587 5587 20

5587 5587 30

5587 5587 30

5587 5587 30

5587 5587 30

5587 5587 30

5587 5587 30

可以看到部门ID相同的数据存储在一个block上。我们为什么推荐上述方法对cluster进行最初的装载呢?这样能够保证如果有些cluster key的相关数据超过了size,仍能使大部分数据聚集在一个block上。这只适用于最初的数据装载,在这以后,可以使用事务对cluster中的table insert数据。

由于cluster中的特殊的数据存储方式,出现了这样一个问题,rowid出现了重复,现在rowid只能在一个table中唯一标识一行数据了(另一种rowid重复出现在transport tablespace的 *** 作后)。

SQL>select rowid from department

2 intersect

3 select rowid from employee

ROWID

------------------

AAAGWQAADAAABXTAAA

AAAGWQAADAAABXTAAB

AAAGWQAADAAABXTAAC

AAAGWQAADAAABXTAAD

PCTFREE存储参数告诉ORACLE什么时候应该将数据块从对象的空闲列表中移出。ORACLE的默认参数是PCTFREE=10;

也就是说,一旦一个INSERT *** 作使得数据块的90%被使用,这个数据块就从空闲列表(freelist)中移出。

PCTUSED存储参数告诉ORACLE什么时候将以前满的数据块加到空闲列表中。当记录从数据表中删除时,数据库的数据块就有空间接受新的记录,

但只有当填充的空间降到PCTUSED值以下时,该数据块才被连接到空闲列表中,才可以往其中插入数据。PCTUSED的默认值是PCTUSED=40。

(1)PCTUSED较高意味着相对较满的数据块会被放置到空闲列表中,从而有效的重复使用数据块的空间,但会导致I/O消耗。

PCTUSED低意味着在一个数据块快空的时候才被放置到空闲列表中,数据块一次能接受很多的记录,因此可以减少I/O消耗,提高性能。

(2)PCTFREE的值较大意味着数据块没有被利用多少就从空闲列表中断开连接,不利于数据块的充分使用。

PCTFREE过小的结果是,在更新时可能会出现数据记录迁移(Migration)的情况。

(注:数据记录迁移(Migration)是指记录在是UPDATE *** 作扩展了一个列后,

PCTFREE参数所指定的空间不够扩展,从而记录被ORACLE强制迁移到新的数据块,发生这种情况将较严重的影响ORACLE的性能,出现更新缓慢)。

PCTFREE的使用

在Oracle中表的每一行数据由唯一的ROWID标记;而Oracle支持的数据类型中有一些长度是可变的,如VARCHAR,当对这些数据进行UPDATE时,

如果块中的可用空间不能容纳UPDATE后的数据行时,Oracle将会把此行移到其它数据块,同时保留此数据行的ROWID不变,

并在原有块中建一指针指向行迁移后的位置。

在这种情况下读取一行数据将需要访问2个数据块,从而导致性能下降。PCTFREE保留的空间就是为确保更改后的数据行可以仍存放于原有数据块中,

避免行迁移的情况发生。

PCTUSED的使用

当块的使用的空间下降到PCTUSED后,此块被重新放回空闲链表(Freelist)中,作为后续Insert的候选块。同样,

设置PCTUSED需要视数据行的特性和Insert、Update、Delete的模式而定,但必须遵守的原则是:db_block_size* (100 - PCTFREE - PCTUSED)必须比行的长度大。

对于数据行长度变化较大的情况,应使用最大行长度来计算PCTUSED,并且应使用较低的PCTUSED值。

因为在执行Insert时,如果数据块的可用空间不能装下一行数据,当块的使用的空间是在PCTUSED之上,Oracle将把此块从Freelist中移走;

当块的使用的空间是在PCTUSED之下,Oracle将会扩展段空间。因此,PCTUSED如果设得过高,将导致段的不断扩展。当数据行长度不大时,

使用缺省的PCTUSED(40)是比较合适的;对于行长度较大的情况,最长的行有可能会占用半个以上的块空间,此时可设置PCTUSED为10。

较小的PCTUSED仅在表中的数据以随机方式被删除,而且仍有一些行长时间保留在块中时,才会造成空间使用上的问题,

因为这些块可能需要较长的时间才能或永远不能重新被用于存放新数据。在这种应用中,如果空间利用率一直处于较低水平,

则需对PCTUSED进行分析和调整。

oracle是否是集群这个问题是一个无效问题

oracle是一种数据库软件,管理自身的数据库。它由oracle软件+oracle数据库组成

类似excel.exe程序,exce=excel.exe+excel.xls

而集群只是利用集群软件把多个节点(机器或者软件)逻辑组成一个大机器。

oracle提供了一个集群软件,11g下叫做cluster。通过他,能让多个机器上的oracle软件共同 *** 作一个数据库。

IBM提供了一个集群软件HACMP,不过IBM的集群并不能真正实现负载。高可用。


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/sjk/9935267.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-03
下一篇 2023-05-03

发表评论

登录后才能评论

评论列表(0条)

保存