Oracle的聚簇表

索引聚簇表
create cluster emp_dept_cluster
(deptno number(2)) size 1024;
size 1024 表示每个聚簇键值关联大约1024字节的数据,
oracle会在用这个数据库块上通过size计算最多可以放多少个簇
如果块是8KB,那么这个块上最多放7个聚簇键

向聚簇中放数据之前,需要先对聚簇建立索引.
create index emp_dept_cluster_idx on cluster emp_dept_cluster;

加载的方式应彩用一一对应的关系.加载完主表之后再加载从表

什么情况下不能用索引聚簇表
1)如果预料到聚簇中的表会大量修改,索引聚簇表会对DML的性能产生负面影响.
2)非常不适合对单表的全表扫描,因为只能引起对其它表的全表扫描
3)频繁对表进行TRUNCATE和加载,因为聚簇中的表是不能TRUNCATE的


SQL> truncate table dept;
truncate table dept
               *
ERROR at line 1:
ORA-03292: Table to be truncated is part of a cluster

如果数据主要用来读,不怎么修改,并且逻辑上与聚簇连接想适合,最好使用索引聚簇表
oracle数据字典就是这样做的

SQL> set autotrace traceonly statistics
SQL> select a.deptno,b.ename from dept_02 a,emp_02 b where a.deptno=b.deptno and
a.deptno='30';

6 rows selected.

Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE
   1    0   MERGE JOIN
   2    1     INDEX (UNIQUE SCAN) OF 'dddd' (UNIQUE)
   3    1     FILTER
   4    3       TABLE ACCESS (FULL) OF 'EMP_02'


Statistics
----------------------------------------------------------
          0 recursive calls
          0 db block gets
          5 consistent gets
          0 physical reads
          0 redo size
        470 bytes sent via SQL*Net to client
        495 bytes received via SQL*Net from client
          2 SQL*Net roundtrips to/from client
          0 sorts (memory)
          0 sorts (disk)
          6 rows processed

SQL> select a.deptno,b.ename from dept a,emp b where a.deptno=b.deptno and a.deptno='30';

6 rows selected.


Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE
   1    0   NESTED LOOPS
   2    1     INDEX (UNIQUE SCAN) OF 'SYS_C002891' (UNIQUE)
   3    1     TABLE ACCESS (CLUSTER) OF 'EMP'


Statistics
----------------------------------------------------------
          0 recursive calls
          0 db block gets
          4 consistent gets --这里可以看出有点优点,在consistent gets上少了一块
          0 physical reads
          0 redo size
        470 bytes sent via SQL*Net to client
        495 bytes received via SQL*Net from client
          2 SQL*Net roundtrips to/from client
          0 sorts (memory)
          0 sorts (disk)
          6 rows processed

SQL> select a.deptno,b.ename from dept a,emp b where a.deptno=b.deptno;

14 rows selected.

Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE
   1    0   NESTED LOOPS
   2    1     TABLE ACCESS (FULL) OF 'EMP'
   3    1     TABLE ACCESS (CLUSTER) OF 'DEPT'


Statistics
----------------------------------------------------------
          0 recursive calls
          0 db block gets
         37 consistent gets --全表扫描真是too bad,没有办法,这里不适用索引聚簇表
          0 physical reads
          0 redo size
        581 bytes sent via SQL*Net to client
        495 bytes received via SQL*Net from client
          2 SQL*Net roundtrips to/from client
          0 sorts (memory)
          0 sorts (disk)
         14 rows processed

SQL> select a.deptno,b.ename from dept_02 a,emp_02 b where a.deptno=b.deptno;

14 rows selected.

Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE
   1    0   NESTED LOOPS
   2    1     TABLE ACCESS (FULL) OF 'EMP_02'
   3    1     INDEX (UNIQUE SCAN) OF 'dddd' (UNIQUE)


Statistics
----------------------------------------------------------
          0 recursive calls
          0 db block gets
          6 consistent gets
          0 physical reads
          0 redo size
        581 bytes sent via SQL*Net to client
        495 bytes received via SQL*Net from client
          2 SQL*Net roundtrips to/from client
          0 sorts (memory)
          0 sorts (disk)
         14 rows processed



 

使用索引聚簇指南
1.考虑对经常在连接语句中访问的表建立聚簇(经常要进行关联的表)。
2.如果表只是偶尔被连接或者它们的公共列经常被修改,则不要聚簇表。
 (修改记录的聚簇键值比在非聚簇的表中修改此值要花费更多的时间,因为Oracle必须将修改的记录移植到其他的块中以维护聚簇)
3.如果经常需要在一个表上进行完全搜索,则不要聚簇这个表
 (对一个聚簇表进行完全搜索比在非聚簇表上进行完全搜索的时间长,Oracle可能要读更多的块,因为表是被一起存储的.)
4.如果经常从一个父表和相应的子表中查询记录,则考虑给1对多(1:*)关系创建聚簇表。
 (子表记录存储在与父表记录相同的数据块中,因此当检索它们时可以同时在内存中,因此需要Oracle完成较少的I/O)
5.如果经常查询同一个父表中的多个子记录,则考虑单独将子表聚簇.
 (这样提高了从相同的父表查询子表记录的性能,而且也没有降低对父表进行完全搜索的性能)。
6.如果经常从所有有相同聚簇键值的表查询出的结果数据超过一个或两个Oracle块,则不要聚簇表.
 (要访问在一个聚簇表中的记录,Oracle读取所有包含那个记录值的全部数据块,如果记录占据了多个数据块,
  则访问一个记录需要读的次数比一个非聚簇的表中访问相同的记录读的次数要多)

 
使用哈希聚簇指南
1.当经常使用有相同列的包含相等条件的查询子句访问表时,考虑使用哈希聚簇来存储表。使用这些列作为聚簇键。
2.如果可以确定存放具有给定聚簇键值的所有记录所需的空间(包括现在的和将来的),则将此表以哈希聚簇存储。
3.如果空间不够,并且不能为将要插入的新记录分配额外的空间,那么不要使用哈希聚簇。
4.如果偶尔创建一个新的、很大的哈希聚簇来保存这样的表是不切实际的,那么不要用哈希聚簇存储经常增长的表。
5.如果经常需要进行全表搜索,并且必须要为表的预期增长中的哈希聚簇分配足够的空间,则不要将此表以哈希聚簇存储。
 (这样的完全检索必须要读分配给哈希聚簇的全部块,即使有些块可能只包含很少的记录.单独地存储表将减少由完全的表检索读取的块的数量)
6.如果你的应用程序经常修改聚簇键的值,则不要将表以哈希聚簇方式存储。
7.不管这个表是否经常与其他表连接,只要进行哈希对于基于以前的指南的表是合适的,那么在哈希聚簇中存储一个表可能是有用的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值