在实际的生产环境中,我们可能不总是那么幸运,我们肯定会碰到两方面的需求。一方面是热块冲突必须解决,另外一方面可能我们还存在一定的应用要对这些数据做范围扫描。在这种情况下,我们必须进行综合的评估,到底哪种需求是主要需求。如果我们优化范围扫描对系统更为有利,那么我们就必须放弃HASH分区;如果解决热块冲突更为重要,那么我们就必须牺牲范围扫描。实际上Oracle就是这样的,任何技术都是矛盾的,都是有缺陷的,否则我们就只需要记住一些准则,就可以成为大师了。Oracle的大师不是那么容易当的,因为在绝大多数情况下,没有永恒的准则。
HASH(HASH CLUSTER TABLE)簇表不是分区表,但是HASH簇表和普通的表(也就是术语是哪个说的堆表,HEAP TABLE)的存储方式是不同的,HASH簇表是簇表的一种,不过HASH簇表的组织方式是根据HASH值的,不同的数据块中存储不同HASH值的行。这样一来,哪怕同时插入的两条记录,也有可能因为某个字段的HASH值不同而存储在不同的数据块中。这样就可以最大限度的减少热块冲突。
Hash Cluster适合于对表的访问主要是等于条件的,很少做根据CLUSTER键值的范围扫描的情况。HASH CLUSTER TABLE除了优化热块冲突外,对于改善大表的SELECT操作也有一定的作用。使用下面的语句可以创建一个HASH簇表:
SQL> CREATE CLUSTER off_clu
2 ( country VARCHAR2(2),
3 postcode VARCHAR2(10) )
4 SIZE 350
5 TABLESPACE case_large_data
6 HASHKEYS 6000;
SQL> CREATE TABLE office
2 ( office_cd NUMBER(3),
3 cost_ctr NUMBER(3),
4 country VARCHAR2(2),
5 postcode VARCHAR2(10) )
6 CLUSTER off_clu(country, postcode);
创建CLUSTER时的主要参数包括:
• HASHKEYS: KEY的数量
• HASH IS: 使用客户自定义的HASH函数
• SIZE: 预留的空间,用以存储相同HASHVALUE的不同的HASHKEY的值。如果HASHKEY的长度比较长,建议设置较大的值
除了HASH分区和HASH CLUSTER TABLE外,我们仍然有很多种方法可以用来减少热块冲突。加大PCTFREE是一种最常用和简单的方法,PCTFREE增加后,平均每个数据块中的记录数也就会减少,从而减少热块冲突的发生机会。
还有一种办法是使用较小的BLOCK SIZE,从9i开始,Oracle提供了一种新技术,就是用户表空间可以设置独立的BLOCK SIZE,而不需要和数据库的缺省BLOCK SIZE相同。这种技术为解决热块冲突提供了另外一种选择。不过使用不同的BLOCK SIZE这种十分优秀的技术在我们的实际应用环境中很少见到。这是因为开发厂商往往不了解这种技术,因此也很少有系统被这样设计。
好了,说了这么长一大篇,可能很多读者都昏昏欲睡了。关于表及相关存储参数的讨论到此先告一个段落,今后我们还会继续讨论这个永恒的话题。从明天开始,老白将通过一个实际的优化案例来重申表结构及参数的设置是如何的重要。