散列簇

散列簇学习

      散列簇这个东西,说实话我也不知道有什么用处,很少会用到。既然看到这里,就学习一下,貌似这个功能是用来处理表的一些索引结构的,实在是看了头大,记下来再说,以后有需要了再慢慢看吧。
 
一、散列簇的适用环境
      散列簇是一种为非簇表提供索引或索引簇的一种方法,它将表存储到一个散列簇,可以改善数据检索的性能。对于索引表或索引簇,Oracle使用存储在单独的索引中的键值来定位表中的行。Oracle会物理地将表中的行存储到散列簇,并根据散列函数的结果来检索它们。
      Oracle使用散列函数来产生散列值(基于特殊的簇键值的数字值分布)。散列簇建类似索引簇的键,可以是单个列或组合列。为了在散列簇中查找或存储行,Oracle将散列函数应用到行的簇键值。产生的散列值对应于簇中的数值块,然后Oracle根据发布的语句在这些数据块上读写。
 
      在簇表或簇中查询存储行时,至少需要执行两个I/O(索引中以及表中的读写),而使用散列函数在散列簇中定位行时不需要I/O,所以至少需要1次I/O。
 
      注:即使决定使用散列方法,表仍然可以在任何列(包括簇键)上具有单独的索引。
 
1、散列方法有用的情况
 
      * 大多数查询是在簇键上的相等查询
      SELECT ... WHERE cluster_key = ... ;
      此时相等条件被散列,并且通常读一次就能找到对应散列键。对比索引表则需要先在索引中找到其键值,再从表中读行。
 
      * 散列簇中的表的大小是基本不变的
      此时可以确定簇中表的行数及其所需空间,如果散列簇中表需要比初始分配更多的空间,则性能将会降低(使用溢出数据块)。
 
2、散列方法无益的情况
 
      * 表上大多数查询是在簇键值的一个范围中检索
      SELECT ... WHERE cluster_key < ... ;
      范围无法被散列,只能全表扫描,而索引是可以将键值排序的
 
    * 表不是静止的,而是经常增长的
 
      * 应用经常对表进行全表扫描,并且很少填充表
      此情况下散列方法的全表扫描需要更长时间
 
    * 无法提供散列簇最终需要的与分配空间
 
二、创建散列簇
 
      CREATE CLUSTER trial_cluster (trialno NUMBER(5,0))
      PTCUSED 80
      PCTFREE 5
      TABLESPACE users
      STORAGE (INITIAL 250K NEXT 50K
      MINEXTENTS 1 MAXEXTENTS 3
      PCTINCREASE 0)
      HASH IS trialno HASHKEYS 150;
 
      CREATE TABLE trial (
      trialno NUMBER(5,0) PRIMARY KEY,
      ...)
      CLUSTER trial_cluster (trialno);
 
      说明:
      1.HASHKEY值指定和限制该簇所使用的散列函数可以产生的唯一的散列值数量(Oracle会取最接近的素数)
      2.如果没有HASH IS子句,Oracle就会使用内部散列函数。
      3.在散列簇上不能创建索引,也不需要在散列簇键上创建索引
 
1、创建单个表散列簇
 
      单个表散列簇提供了对表中的行的快速访问。必须在散列键和数据行之间存在一对一的映射。
 
      CREATE CLUSTER peanut (variety NUMBER)
      SIZE 512 SINGLE TABLE HASHKEY 500;
 
      注:SINGLE TABLE 选项仅对散列簇有效,且必须指定HASHKEYS
 
2、控制散列簇的空间使用
 
      ① 选择键
      选择正确的簇键取决于针对簇表所发布的最常用的查询类型(看最常用那个键来选择行)。
      最典型的簇键就是包含表的整个主键。
 
      ② 设置HASH IS
      仅当簇键是NUMBER数据类型、包含均匀分布的整数的单个列时,才指定HASH IS参数。
 
      ③ 设置SIZE
      应将SIZE设置成为保持任何给定散列键的所有行所需的空间的平均数
      * 若散列簇仅包含单个表,且表中行的散列键值唯一,则SIZE为簇中平均的行大小
      * 若散列簇包含多个表,则设置SIZE为:为保持与代表性的散列值相关的所有行所需的空间平均数
      * 若散列簇不使用内部散列函数,且期望很少或没有冲突,则使用SIZE初始值
      * 若预料到插入时经常冲突,则为了存储行而分配溢出数据块的高可用性,按需要适当增加SIZE
     
      ④ 设置HASHKEYS
      为散列簇中行的最大分布,且Oracle会自动舍入到最近素数
 
3、控制散列簇的空间举例
     
      假设数据块大小为2K,平均每个数据块可用数据空间为1950B
 
      例1:
      现打算将emp表装载进一个散列簇,大多数查询按职员号码检索职员记录,你估计,在任何给定时间中emp表最大的行数是10000,且平均行大小是55字节。
      此时应将empno作为簇键,因为该列包含唯一整数,所以可不使用内部散列函数。SIZE可被设置成平均行大小(55字节)。注意,给每个数据块赋予了34个散列键。HASHKEYS可被设置成表中的行数(10000)。Oracle自动转换为最接近的素数(10007)。
 
      CREATE CLUSTER emp_cluster (empno NUMBER)
      ...
      SIZE 55
      HASH IS empno HASHKEYS 10000;
 
      例2:
      按部门号码进行检索行,其他条件类似。且每个部门平均10个职员,部门号码按10递增(0,10,20,30,...)
      此时应将deptno作为簇键,又因为该列包含均匀分布整数,所以可以不使用内部散列函数。SIZE的初始值是55字节*10,因此每个数据块被赋予3个散列键。如果预料到某些冲突,且希望数据检索的性能最好,可稍微更改所估计的SIZE值,以预防需要溢出数据块而带来冲突,调整12%的SIZE到620字节
      HASHKEYS可以被设置成唯一的部门号码的个数(1000),Oracle自动转换为最接近的素数(1009)。
 
      CREATE CLUSTER emp_cluster (deptno NUMBER )
      ...
      SIZE 620
      HASH IS deptno HASHKEYS 1000;
 
4、估计散列簇所需的空间大小
 
      依据SIZE和HASHKEYS的设置值,Oracle保证最初分配的空间足够存储散列表。如果对INITIAL、NEXT、MINEXTENTS的设置值不能满足簇的大小,则分配增加的盘区直到至少满足 SIZE*HASHKEYS
 
      例如:假设数据块大小为2K,每个数据块可用数据空间大约为1900字节,且CREATE CLUSTER语句中指定如下:
      STORAGE (INITIAL 100K
      NEXT 150K
      MINEXTENTS 1
      PCTINCREASE 0)
      SIZE 1500
      HASHKEYS 100
      则以上例子中每个数据块仅可赋予一个散列键,因此散列簇所需的初始空间至少是100*2K,所以设置的存储参数无法满足需求。因此需要分配给该散列簇一个100K的出示盘曲和一个150K的第2盘区。
 
      如果HASH参数指定为:
      SIZE 500 HASHKEYS 100
      则此时可以给每个数据块赋予3个散列键,此时需要的初始化空间是34*2K,可以满足需求。
 
三、更改散列簇
 
      ALTER CLUSTER emp_dept ...;
      --与簇相同
 
四、删除散列簇
 
      DROP CLUSTER emp_dept;
      --与簇相同
 
五、散列簇相关信息
 
      DBA|ALL|USER_CLUSTERS:该视图包含了散列簇
      DBA|USER_CLU_COLUMNS:该视图包含了散列簇
      DBA|ALL|USER_CLUSTER_HASH_EXPRESSIONS:列出用于散列簇的散列函数

转自:http://www.blogjava.net/decode360/archive/2009/03/18/291817.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值