散列簇学习
				
		
		
				
				 
		
				
						    散列簇这个东西,说实话我也不知道有什么用处,很少会用到。既然看到这里,就学习一下,貌似这个功能是用来处理表的一些索引结构的,实在是看了头大,记下来再说,以后有需要了再慢慢看吧。
				
		
		
				
				 
		
				
						
								一、散列簇的适用环境
						
				
		
		
				
				 
		
				
						    散列簇是一种为非簇表提供索引或索引簇的一种方法,它将表存储到一个散列簇,可以改善数据检索的性能。对于索引表或索引簇,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:列出用于散列簇的散列函数