首页 | 摘要显示 | 上一页 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 下一页

Oracle Archives

April 27, 2007

Oracle应当增加一种基于Hash算法的索引

    Hash是非常高效的一种查找算法, Oracle中的Hash Join更是声名远播, 还有Hash Cluster表, 可以获得很好的性能. 现在的B*Tree结构的索引, 虽然很好, 但在很繁忙的系统中, 还是有一些不足, 比较典型的是在索引的根结点上, 发生Split时很容易引起数据库的问题. 另外从Root块到Branch块, 再到Leaf块, 最后到获得表的记录, 需要访问比较多的结点.

    既然Hash算法能用于表, 那么也能用于索引. 因为索引从另外一个角度来说, 也象一个表, 象一个包括了索引列加上ROWID组成的表. 通过这种Hash类型的索引, 第一个可以将读一条记录的Gets减少到2, 同时也没有了Root块和Branch块的Split问题, 实在是值得考虑的一种新的索引类型.

    其实通过Context接口, 已经可以很容易地实现这样的功能, 谁有写过自定义的Context索引类型?

    在Oracle中Hash Cluster不一定要求字段是数字类型的, 因此支持Hash Index并不需要改动很多吧? 如下所示:

SQL> create cluster c_hashidx (col1 varchar2(30)) hashkeys 128;

Cluster created.

    不知道现在的哪种数据库中已经有这种类型的索引了? 听说在IBM DB2中, 创建索引时可以指定一些包含(Including)的列, 这些列的值会在索引中存放, 以进行行过滤, 但这些字段并不参于索引中记录的排序, 这个功能要是能在Oracle中有就好了!

对Hash Cluster表的一些进一步测试之一

    在前面的例子中, 我们都只是做了一些小批量数据, 如果我的Hash Cluster表有几个GB或几十个GB的大小时, 又怎么样呢? 下面进行的是我在笔记本上的测试, 用于测试的表的大小是100MB, 进行测试时的数据是50万条. 测试的目的是为了要证明Hash Cluster是否可能用于大数据量的表中, 即验证Oracle内建的Hash函数是否是高效的. 创建Hash Cluster的句语是:

CREATE CLUSTER C_T_OBJECTS (OBJECT_ID NUMBER(38,0))
SIZE 8192 SINGLE TABLE HASHKEYS 12800;    

    在100MB的DB_CACHE_SIZE下进行测试:

21:48:10 SQL> SELECT HASH_VALUE, BUFFER_GETS, EXECUTIONS
21:48:54   2  FROM V$SQL WHERE HASH_VALUE=3523526785;

HASH_VALUE BUFFER_GETS EXECUTIONS
---------- ----------- ----------
3523526785      540786     540696

    在50MB的DB_CACHE_SIZE下进行测试, 可以看出DB_CACHE_SIZE的大小不是很关键:

21:51:37 SQL> SELECT HASH_VALUE, BUFFER_GETS, EXECUTIONS
21:51:44   2  FROM V$SQL WHERE HASH_VALUE=3523526785;

HASH_VALUE BUFFER_GETS EXECUTIONS
---------- ----------- ----------
3523526785      540790     540696

    当另外一个会话在进行数据装载时, Cost将会增加, 这是因为Consistent Gets引起的, 从平均值来说仍是十分高效的.

22:03:19 SQL> SELECT HASH_VALUE, BUFFER_GETS, EXECUTIONS
22:03:35   2  FROM V$SQL WHERE HASH_VALUE=3523526785;

HASH_VALUE BUFFER_GETS EXECUTIONS
---------- ----------- ----------
3523526785      740454     540696

    明天将在比较好的机器上, 测试10G大小左右的真实数据. 另外一个问题是如何去验证是否存在比较严重的数据分布(算出来的Hash值)不均匀的问题?

April 28, 2007

对Hash Cluster表的一些进一步测试之二

    今天早上用真实的数据进行了第二次测试, 一是验证我这种定义SIZE和HASHKEYS参数的方法有没有问题, 另外一个是难证Oracle自带的Hash函数是否高效. 为此我选取了1000万条真实的记录, 表的大小大约是1.5个G, 我将Cluster的HASHKEYS * SIZE设成2G左右, 语句如下:

CREATE CLUSTER C_USER_HOST_ID_LOOKUP (USER_ID NUMBER(38,0))
    SIZE 8192 SINGLE TABLE HASHKEYS 262144;

    用sqlldr装载这些数据却用了1个小时, 这是因为你不能用Direct方式, 而且每条记录是随机存放的, 而不是连续存放的, 所以比较慢. 装载完成后, 用如下脚本进行验证. 其中的SELECT语句可是要执行大约1000万次的.

DECLARE
   TEMP VARCHAR2(64);
BEGIN
   FOR REC IN (SELECT USER_ID FROM CR_FLOUTEST) LOOP
      SELECT /* FLOU_TEST */ userid INTO TEMP FROM CR_FLOUTEST
             WHERE USER_ID = REC.USER_ID;
   END LOOP;
END;
/

    最后在V$SQL中检查这个SELECT语句的执行情况, 发现是相当的高效的. 表明我选择的SIZE和HASHKEYS参数没有问题, 也表明Oracle的Hash算法很好.

SQL> SELECT HASH_VALUE, BUFFER_GETS, EXECUTIONS
  2  FROM V$SQL WHERE HASH_VALUE=2716314996;

HASH_VALUE BUFFER_GETS EXECUTIONS
---------- ----------- ----------
2716314996     9998912    9998777

    在做完这些验试后, 将决定是不是要将有二亿条记录的表搞成Hash Cluster.

July 12, 2007

Oracle 11g性能提升 -- Server Result Cache

    10g几乎没有关心, 现在都现11g了, 得关心一下了, 要不然就落伍了. Cache始终是提升性能的重要技术, 在Oracle 11g中增加了一种Server Result Cache, 第一眼看到这个名字, 我觉得和MySQL的Query Cache是差不多的技术, 不过仔看白皮书, 还是要比MySQL进步多了.

    谁可以共享这些数据? MySQL的Query Cache是根据SQL的文本来匹配的, 只有Query的文本一模一样时才可以共享, 而Oracle的Server Result Cache则只要执行计划一样或部份一样, 并且生命周期一样, 则就可以共享了. 当下面的表数据改变了, Oracle会自动清除这个Cache, 以确保查询结果的正确性. 在以读为主要的系统中, 宣称性能可以提升一倍.

    这块内存从SGA中分配, 由RESULT_CACHE_MAX_SIZE控制. Oracle允许你在系统, 会话, 表和语句级(Hint:result_cache)控制是否使用Server Result Cache技术. Oracle提供一个PL/SQL包及相应视图来管理这个Cache区域.

    好好利用这一点, 的确可以提升读的性能, 等11g可以下载了得好好试试.

Oracle 11g性能提升 -- Consistent Client Cache

    10g几乎没有关心, 现在都现11g了, 得关心一下了, 要不然就落伍了. Cache始终是提升性能的重要技术. 除了在前面讲的Server Result Cache, Oracle 11g还增加了一种Client Cache. 第一眼看到时, 我猜测可能和在程序中用数组保存一些查找表差不多, 不过仔看白皮书, 还是要比自已写程序来得方便许多.

    这是一种在Oracle Client端的缓冲技术, 通过将中间结果或整个表缓冲在客户端, 当客户端发出查询请求时, Oracle可以直接在这个缓冲区中返回记录, 而不需要去和数据库打交道, 可以大大地着少和服务器端的网络来回, 降底服务器上的SQL调用, 根据Benchmarks测试, 对于只读或极少更新的表, 总的消耗时间可以降低500%, 而服务器上的CPU时间可以降低200%.

    要使用这个Cache功能, 也很简单, 首先要使用Oracle 11g的OCI客户端, 如: JDBC-OCI, ODBC, ODB.NET, PHP, Perl等, 无须要去更改现有的程序代码; 其次需要在数据库端指定CLIENT_RESULT_CACHE_SIZE参数来指定这一块Cache的大小, 如果为0则表示禁用. 也可以在客户端进行个别设置.

    希望Oracle可以尽快提供11g的有关文档下载.

上一页 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 下一页

当前分类: Oracle

Creative Commons License
本站版权: 共用创作 CC
署名-非商业性-相同方式分享
本站基于MT-3.36免费版
(©)版权所有, 2004 - 2008, www.AnySQL.net, 保留所有权利.
MSN: loufangxin(a)msn.com, Mail: anysql(at)126.com/support(at)iamdba.com, Skype ID:anysql