Decode360's Blog

业精于勤而荒于嬉 QQ:150355677 MSN:decode360@hotmail.com

  BlogJava :: 首页 :: 新随笔 :: 联系 ::  :: 管理 ::
  302 随笔 :: 26 文章 :: 82 评论 :: 0 Trackbacks
散列簇学习
 
 
一、散列簇的适用环境
 
    散列簇是一种为非簇表提供索引或索引簇的一种方法,它将表存储到一个散列簇,可以改善数据检索的性能。对于索引表或索引簇,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:列出用于散列簇的散列函数
 




-The End-

posted on 2009-03-18 22:23 decode360-3 阅读(409) 评论(0)  编辑  收藏 所属分类: DBA

只有注册用户登录后才能发表评论。


网站导航: