Hash Cluster的表可以在没有索引的情况下, 获得对表的极快访问, 这种访问的逻辑读比维一性索引还有效. 在这儿有一张表T_OBJECTS, 其中的OBJECT_ID是主键, 大量的SQL语句都是根据OBJECT_ID去访问其他字段, 通过索引的情况下每次执行的逻辑读已经只有3了(Index Root->Leaf->Table), 但是就是这样一句简单的SQL的逻辑读占据了大半. 因此考虑到使用Single Hash Cluster表来进行调优. 应当如何来创建这个Cluster呢? 决定Cluster性能的主要有两个因素: SIZE和HASHKEYS.
下面是我的思路, 首先分析一下现在的表, 获得比较准确的块数.
SQL> SELECT BLOCKS FROM USER_TABLES WHERE TABLE_NAME='T_OBJECTS';
BLOCKS
----------
118
因为在这个情况下, 数据分布均匀, 因此我只要将HASHKEYS定义为块数就已经比较好了, 实际上为了更安全, 选择一个比较大的值, 如在这儿我选择144. 而SIZE就直接选择块的大小好了.
SQL> CREATE CLUSTER C_T_OBJECTS (OBJECT_ID NUMBER(38,0))
2 SIZE 8192 SINGLE TABLE HASHKEYS 144;
Cluster created.
接下来创建一个CT_OBJECTS的Cluster表, 并将T_OBJECTS表的记录填充进去. 在这个例子中, 我用下面代码去检查所有的行, 目标是要检测新的Cluster表的性能:
SQL> DECLARE
2 TEMP NUMBER:=0;
3 BEGIN
4 FOR REC IN (SELECT OBJECT_ID FROM T_OBJECTS) LOOP
5 SELECT DATA_OBJECT_ID INTO TEMP FROM CT_OBJECTS
6 WHERE OBJECT_ID=REC.OBJECT_ID;
7 END LOOP;
8 END;
9 /
然后找到这个SQL语句的Hash Value, 从V$SQL视图中去检查一下执行的效率.
SQL> SELECT HASH_VALUE, BUFFER_GETS, EXECUTIONS
2 FROM V$SQL WHERE HASH_VALUE=3267226907;
HASH_VALUE BUFFER_GETS EXECUTIONS
---------- ----------- ----------
3267226907 9464 9462
可以看到这个SQL语句是很有效的, 这种技术可以推荐用在OLTP系统中.
留言 (3)
需要注意的是,如果hash cluster需要频繁变化的话效果就不会太好了,overflow会严重影响性能
Posted by wanghai | Apr 26, 2007 4:52 PM
变化也是没事的, 只要记录不变长, 及不改变分布就可以, 将HASHKEYS设得比Blocks多一些的话, 应当可以使用.
Posted by anysql | Apr 26, 2007 5:00 PM
如果这个表需要进行频繁的变化呢?
有两种情况:
1.大记录量的更新和删除
2.大记录量的增加
会有影响吗?
比如,这个例子可能不恰当,比如我的日志表,每多一条记录,就有一个对应的log id,每次都是根据log id查询其他记录信息,如果关于这个log id建立cluster,合适吗?日志表在不断增加中的啊
Posted by iceinwater | Dec 4, 2007 2:06 PM