oracle数据库表_笔记7:索引聚簇表(续)
索引聚簇表(续)
下面再根据聚簇SIZE为1200重新创建,会发现:
sys@ORCL> create cluster emp_dept_cluster
2 (deptno number(2))
3 size 1200
4 /
Cluster created.
sys@ORCL> create index emp_dept_cluster_idx
2 on
3 cluster emp_dept_cluster
4 /
Index created.
sys@ORCL> create table dept
2 (deptno number(2) primary key,
3 dname varchar2(14),
4 loc varchar2(13)
5 )
6 cluster emp_dept_cluster(deptno)
7 /
Table created.
sys@ORCL> create table emp
2 (empno number primary key,
3 ename varchar2(10),
4 job varchar2(9),
5 mgr number,
6 hiredate date,
7 sal number,
8 comm number,
9 deptno number(2) references dept(deptno)
10 )
11 cluster emp_dept_cluster(deptno)
12 /
Table created.
sys@ORCL> insert into dept
2 (deptno,dname,loc)
3 select deptno+r,dname,loc
4 from scott.dept,
5 (select level r from dual connect by level<10);
36 rows created.
sys@ORCL> insert into emp
2 (empno,ename,job,mgr,hiredate,sal,comm,deptno)
3 select rownum,ename,job,mgr,hiredate,sal,comm,deptno+r
4 from scott.emp,
5 (select level r from dual connect by level <10);
126 rows created.
1 select min(count(*)),max(count(*)),avg(count(*))
2 from dept
3* group by dbms_rowid.rowid_block_number(rowid)
sys@ORCL> /
MIN(COUNT(*)) MAX(COUNT(*)) AVG(COUNT(*))
------------- ------------- -------------
6 66
sys@ORCL> select *
2 from (
3 select dept_blk,emp_blk,
4 case when dept_blk <> emp_blk then '*' end flag,
5 deptno
6 from (
7 select dbms_rowid.rowid_block_number(dept.rowid) dept_blk,
8 dbms_rowid.rowid_block_number(emp.rowid) emp_blk,
9 dept.deptno
10 from emp,dept
11 where emp.deptno=dept.deptno
12 )
13 )
14 where flag='*'
15 order by deptno
16 /
no rows selected
现在每块只存储了6个DEPTNO值,这样就留出了足够的空间使所有EMP数据都能与相应DEPT记录存储在同一个块上。
许多人错误地认为一个rowid能唯一地标识数据库中的一行,给定一个rowid,就能得出这一行来自哪个表。实际上,这是做不到的。从聚簇可以得到(而且将得到)重复的rowid,例如,执行以上代码后:
sys@ORCL> select rowid from emp
2 intersect
3 select rowid from dept;
ROWID
------------------
AAAS/dAABAAAXDBAAA
AAAS/dAABAAAXDBAAB
AAAS/dAABAAAXDBAAC
AAAS/dAABAAAXDBAAD
AAAS/dAABAAAXDBAAE
AAAS/dAABAAAXDBAAF
AAAS/dAABAAAXDCAAA
AAAS/dAABAAAXDCAAB
AAAS/dAABAAAXDCAAC
AAAS/dAABAAAXDCAAD
AAAS/dAABAAAXDCAAE
AAAS/dAABAAAXDCAAF
AAAS/dAABAAAXDDAAA
AAAS/dAABAAAXDDAAB
AAAS/dAABAAAXDDAAC
AAAS/dAABAAAXDDAAD
AAAS/dAABAAAXDDAAE
AAAS/dAABAAAXDDAAF
AAAS/dAABAAAXDEAAA
AAAS/dAABAAAXDEAAB
AAAS/dAABAAAXDEAAC
AAAS/dAABAAAXDEAAD
AAAS/dAABAAAXDEAAE
AAAS/dAABAAAXDEAAF
AAAS/dAABAAAXDFAAA
AAAS/dAABAAAXDFAAB
AAAS/dAABAAAXDFAAC
AAAS/dAABAAAXDFAAD
AAAS/dAABAAAXDFAAE
AAAS/dAABAAAXDFAAF
AAAS/dAABAAAXDGAAA
AAAS/dAABAAAXDGAAB
AAAS/dAABAAAXDGAAC
AAAS/dAABAAAXDGAAD
AAAS/dAABAAAXDGAAE
AAAS/dAABAAAXDGAAF
36 rows selected.
DEPT中为各行分配的每个rowid也同时分配给了EMP中的行。这是因为,要由表和行ID共同地唯一标识一行。Rowid伪列只是在一个表中唯一。
许多人认为聚簇对象是一种神秘的对象,以为没有人用它。事实上,每次使用Oracle的时候都会使用聚簇。例如,许多数据字典就存储在各个聚簇中:
sys@ORCL> break on cluster_name
sys@ORCL> select cluster_namek,table_name
2 from user_tables
3 where cluster_name is not null
4 order by 1;
CLUSTER_NAME TABLE_NAME
------------------------------ ------------------------------
C_COBJ# CDEF$
CCOL$
C_FILE#_BLOCK# SEG$
UET$
C_MLOG# MLOG$
SLOG$
C_OBJ# SUBCOLTYPE$
NTAB$
REFCON$
OPQTYPE$
ICOLDEP$
VIEWTRCOL$
LIBRARY$
ASSEMBLY$
ATTRCOL$
TYPE_MISC$
COLTYPE$
LOB$
COL$
ICOL$
IND$
TAB$
CLU$
C_OBJ#_INTCOL# HISTGRM$
C_RG# RGROUP$
RGCHILD$
C_TOID_VERSION# ATTRIBUTE$
METHOD$
COLLECTION$
PARAMETER$
RESULT$
TYPE$
C_TS# TS$
FET$
C_USER# TSQ$
USER$
EMP_DEPT_CLUSTER EMP
DEPT
HASH_CLUSTER T_HASHED
SMON_SCN_TO_TIME_AUX SMON_SCN_TIME
40 rows selected.
sys@ORCL>
可以看到,与对象相关的大多数数据都存储在一个聚簇(C_OBJ#聚簇)中:16(17)个表都在同一个块中。这里存储的主要是与列相关的信息,所以关于表或索引列集的所有信息都物理地存储在同一个块上。这是有道理的:Oracle解析一个查询时,希望访问所引用的表中所有列的数据。如果这些数据分布得到处都是是,就要花一些时间才能把它们收集起来。如果数据都在一个块上,通常就能很容易地得到。
什么时候要使用聚簇呢?可能返过来回答什么时候不应该使用聚簇会更容易一些。
.如果预料到聚簇中的表会大量修改:必须知道,索引聚簇会对DML的性能产生某种负面影响,特别是INSERT语句。管理聚簇中的数据需要做更多的工作。由于要非常小心地存储数据,因此存储(插入)数据会占用很长时间。
.如果需要对聚簇中的表执行全表扫描:不只是必须对表中的数据执行全面扫描,还必须对(可能的)多个表中的数据进行全面扫描。由于需要扫描更多的数据,所以全表扫描耗时更久。
.如果要对表进行分区:聚簇中的表不能分区,聚簇也不能分区。
.如果认为需要频繁地TRUNCATE和加载表:聚簇中的表不能截除。因为聚簇在一个块上存储了多个表,必须删除聚簇表中的行。
因此,如果数据主要用于读(这并不表示“从来不写”,聚簇表完全可以修改),而且要通过索引来读(可以是聚簇键索引,也可以是聚簇表上的其他索引),另外会频繁地把这些信息联结在一起,此时聚簇就很适合。应该找出逻辑上相关而且总是一起使用的表,设计Oracle数据字典的人就是这样做的,他们把与列相关的所有信息都聚簇在一起。
http://www.52ij.com/jishu/5287.htmloracle数据库表_笔记7:索引聚簇表
本文来源 我爱IT技术网 http://www.52ij.com/jishu/5288.html 转载请保留链接。
- 评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)
-
